• mybatis源码解析


    mybatis源码解析
    mybatis原理:
        1.创建sessionFactory
            sessionFactory = SqlSessionFactoryBuilder.build(Configuration config)
        2.MyBatis的SQL查询流程
            原理:利用元数据获取结构集
                ResultSetMetaData metaData = resultSet.getMetaData();
                int column = metaData.getColumnCount();
                for (int i = 1; i <= column; i++) {
                    JdbcType jdbcType = JdbcType.forCode(metaData.getColumnType(i));
                    typeHandlers.add(TypeHandlerRegistry.getTypeHandler(jdbcType));
    
                    columnNames.add(metaData.getColumnName(i));
                }
            步骤:
                sqlSession = sessionFactory.openSession();
                User user = sqlSession.selectOne("UserDao.findById", 1);
                selectOne
                    selectList
                        query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler)
                            query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
                                queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
                                    SimpleExecutor.doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) 
                                    {
                                        Configuration configuration = ms.getConfiguration();
                                        StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
                                        /* SQL查询参数的设置 */
                                        stmt = prepareStatement(handler, ms.getStatementLog());
                                        /* SQL查询操作和结果集封装 */
                                        return handler.<E>query(stmt, resultHandler);
                                    }
                SimpleExecutor
                    {
                        /* SQL查询参数的设置 */
                        Statement prepareStatement(StatementHandler handler, Log statementLog)
                        {
                            /* 获取Connection连接 */
                            Connection connection = getConnection(statementLog);
                            /* 准备Statement */
                            stmt = handler.prepare(connection, transaction.getTimeout());
                            /* 设置SQL查询中的参数值 */
                            handler.parameterize(stmt) 
                            {
                                DefaultParameterHandler.setParameters(PreparedStatement ps)
                                {
                                    /** 设置SQL参数值,从ParameterMapping中读取参数值和类型,然后设置到SQL语句中 */
                                    List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
                                    for (int i = 0; i < parameterMappings.size(); i++) {
                                        ParameterMapping parameterMapping = parameterMappings.get(i);
                                        if (parameterMapping.getMode() != ParameterMode.OUT) {
                                            String propertyName = parameterMapping.getProperty();    
                                            Object value = getValueByPropertyName(propertyName);
                                            ...
                                            TypeHandler typeHandler = parameterMapping.getTypeHandler();
                                            JdbcType jdbcType = parameterMapping.getJdbcType();
                                            if (value == null && jdbcType == null) {
                                                jdbcType = configuration.getJdbcTypeForNull();
                                            }
                                            typeHandler.setParameter(ps, i + 1, value, jdbcType);
                                        }
                                    }
                                }
                            }
                            return stmt;
                        }
                        
                        /* SQL查询操作和结果集封装 */
                        <E> List<E> query(Statement statement, ResultHandler resultHandler)
                        {
                            PreparedStatement ps = (PreparedStatement) statement;
                            ps.execute(); // 执行查询操作
                            // 执行结果集封装
                            return resultSetHandler.<E> handleResultSets(ps) {
                                DefaultReseltSetHandler {
                                    List<Object> handleResultSets(Statement stmt) {
                                        /* 获取第一个ResultSet,同时获取数据库的MetaData数据,包括数据表列名、列的类型、类序号等。这些信息都存储在了ResultSetWrapper中了*/
                                        ResultSetWrapper rsw = getFirstResultSet(stmt);
                                        while(rsw != null && resultMapCount > resultSetCount) { // 数量多于1条
                                            handleResultSet(rsw, resultMap, multipleResults, null) { // 处理行结果
                                                handleRowValues(rsw, resultMap, null, RowBounds.DEFAULT, parentMapping) {
                                                    handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping) { // 封装数据
                                                        while (shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) { // 获取行数据
                                                            Object rowValue = getRowValue(rsw, discriminatedResultMap) {
                                                                // createResultObject为新创建的对象,数据表对应的类
                                                                Object rowValue = createResultObject(rsw, resultMap, lazyLoader, null);
                                                                // 把数据填充进去,metaObject中包含了resultObject信息
                                                                foundValues = foundValues || applyAutomaticMappings(rsw, resultMap, metaObject, null) {
                                                                    // 这里进行for循环调用,因为user表中总共有7列,所以也就调用7次
                                                                    for (UnMappedColumnAutoMapping mapping : autoMapping) {
                                                                        // 这里将esultSet中查询结果转换为对应的实际类型
                                                                        final Object value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);
                                                                        if (value != null) foundValues = true;
                                                                        metaObject.setValue(mapping.property, value) { // 设值
                                                                            PropertyTokenizer prop = new PropertyTokenizer(name);
                                                                            if (prop.hasNext()) {
                                                                                MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
                                                                                value = objectWrapper.instantiatePropertyValue(name, prop, objectFactory);
                                                                                // metaValue.setValue方法最后会调用到Java类中对应数据域的set方法,这样也就完成了SQL查询结果集的Java类封装过程。
                                                                                metaValue.setValue(prop.getChildren(), value);
                                                                            } else {
                                                                                objectWrapper.set(prop, value);
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                                return foundValues;
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
  • 相关阅读:
    取某个关键词以及之后的数据
    从SQL下载大量数据到Excel
    SQL 分页
    whereis linux文件搜索
    crontab Linux定时器工具
    Angular
    工具
    百度OAuth2.0登录
    JS事件学习 拖拽,鼠标键盘事件实例汇总
    信息栏滚动效果学习总结
  • 原文地址:https://www.cnblogs.com/ice-line/p/10572763.html
Copyright © 2020-2023  润新知