zoukankan      html  css  js  c++  java
  • mybatis源码阅读-执行器StatementHandle和ParameterHandler(五)

    StatementHandle

    类图

    各个实现类的作用

    SimpleStatementHandler 用于使用Statement操作数据库(不会使用参数化查询?)

    PreparedStatementHandler 用于使用PreparedStatement操作数据库(会使用参数化查询)

    CallableStatementHandler 用于使用CallableStatement 操作数据库(主要是执行存储过程)

    RoutingStatementHandler 待定

    StatementHandler调用时机

    Executor部分代码

     public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
            Statement stmt = null;
    
            int var6;
            try {
                Configuration configuration = ms.getConfiguration();
                //获得对应的statementHandler 可以是SimpleStatementHandler PreparedStatementHandler CallableStatementHandler
                StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, (ResultHandler)null, (BoundSql)null);
                //通过StaementHandler设置参数
                stmt = this.prepareStatement(handler, ms.getStatementLog());
                //调用update方法获得返回结果 内部使用Statement操作数据库
                var6 = handler.update(stmt);
            } finally {
                this.closeStatement(stmt);
            }
    
            return var6;
        }

    SimpleStatementHandler

    public class SimpleStatementHandler extends BaseStatementHandler {
        public SimpleStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
            super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
        }
    
        /**
         * 通过Staement执行修改
         * @param statement
         * @return
         * @throws SQLException
         */
        public int update(Statement statement) throws SQLException {
            //获得sql语句 boundSql接口 根据MapperStatement获得
            String sql = this.boundSql.getSql();
            Object parameterObject = this.boundSql.getParameterObject();
            KeyGenerator keyGenerator = this.mappedStatement.getKeyGenerator();
            int rows;
            if (keyGenerator instanceof Jdbc3KeyGenerator) {
                statement.execute(sql, 1);
                rows = statement.getUpdateCount();
                keyGenerator.processAfter(this.executor, this.mappedStatement, statement, parameterObject);
            } else if (keyGenerator instanceof SelectKeyGenerator) {
                statement.execute(sql);
                rows = statement.getUpdateCount();
                keyGenerator.processAfter(this.executor, this.mappedStatement, statement, parameterObject);
            } else {
                statement.execute(sql);
                rows = statement.getUpdateCount();
            }
    
            return rows;
        }
    
        public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {
            String sql = this.boundSql.getSql();
            statement.execute(sql);
            return this.resultSetHandler.handleCursorResultSets(statement);
        }
        //根据connection创建Statement
        protected Statement instantiateStatement(Connection connection) throws SQLException {
            return this.mappedStatement.getResultSetType() != null ? connection.createStatement(this.mappedStatement.getResultSetType().getValue(), 1007) : connection.createStatement();
        }
        //设置参数 由于Staement不支持?参数化查询 sql语句写死参数 所以实现是空的
        public void parameterize(Statement statement) throws SQLException {
        }
    }

    PreparedStatementHandler

    public class PreparedStatementHandler extends BaseStatementHandler {
        public PreparedStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
            super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
        }
    
        public int update(Statement statement) throws SQLException {
            PreparedStatement ps = (PreparedStatement)statement;
            ps.execute();
            int rows = ps.getUpdateCount();
            Object parameterObject = this.boundSql.getParameterObject();
            KeyGenerator keyGenerator = this.mappedStatement.getKeyGenerator();
            keyGenerator.processAfter(this.executor, this.mappedStatement, ps, parameterObject);
            return rows;
        }
        //根据connection创建PrepareStatement
        protected Statement instantiateStatement(Connection connection) throws SQLException {
            String sql = this.boundSql.getSql();
            if (this.mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
                String[] keyColumnNames = this.mappedStatement.getKeyColumns();
                return keyColumnNames == null ? connection.prepareStatement(sql, 1) : connection.prepareStatement(sql, keyColumnNames);
            } else {
                return this.mappedStatement.getResultSetType() != null ? connection.prepareStatement(sql, this.mappedStatement.getResultSetType().getValue(), 1007) : connection.prepareStatement(sql);
            }
        }
        //设置参数
        public void parameterize(Statement statement) throws SQLException {
            //交给parameterHandler处理parameterHandler是根据MappedStatement中获得
            this.parameterHandler.setParameters((PreparedStatement)statement);
        }
    }

    参数设置是委托给ParameterHandler处理的

    CallableStatementHandler

    public class CallableStatementHandler extends BaseStatementHandler {
        public CallableStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
            super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
        }
    
        public int update(Statement statement) throws SQLException {
            CallableStatement cs = (CallableStatement)statement;
            cs.execute();
            int rows = cs.getUpdateCount();
            Object parameterObject = this.boundSql.getParameterObject();
            KeyGenerator keyGenerator = this.mappedStatement.getKeyGenerator();
            keyGenerator.processAfter(this.executor, this.mappedStatement, cs, parameterObject);
            this.resultSetHandler.handleOutputParameters(cs);
            return rows;
        }
        //根据连接创建  CallStatement
        protected Statement instantiateStatement(Connection connection) throws SQLException {
            String sql = this.boundSql.getSql();
            return this.mappedStatement.getResultSetType() != null ? connection.prepareCall(sql, this.mappedStatement.getResultSetType().getValue(), 1007) : connection.prepareCall(sql);
        }
        //设置参数
        public void parameterize(Statement statement) throws SQLException {
            this.registerOutputParameters((CallableStatement)statement);
            this.parameterHandler.setParameters((CallableStatement)statement);
        }
    }

    ParameterHandler

    类图

    DefaultParameterHandler

    public class DefaultParameterHandler implements ParameterHandler {
        private final TypeHandlerRegistry typeHandlerRegistry;
        private final MappedStatement mappedStatement;
        private final Object parameterObject;
        private BoundSql boundSql;
        private Configuration configuration;
    
        public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
            this.mappedStatement = mappedStatement;
            this.configuration = mappedStatement.getConfiguration();
            this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
            this.parameterObject = parameterObject;
            this.boundSql = boundSql;
        }
    
        public Object getParameterObject() {
            return this.parameterObject;
        }
    
        public void setParameters(PreparedStatement ps) {
            ErrorContext.instance().activity("setting parameters").object(this.mappedStatement.getParameterMap().getId());
            //获得BoundSql里面的ParameterMapping 内部保存的是参数的映射
            List<ParameterMapping> parameterMappings = this.boundSql.getParameterMappings();
            if (parameterMappings != null) {
                for(int i = 0; i < parameterMappings.size(); ++i) {
                    ParameterMapping parameterMapping = (ParameterMapping)parameterMappings.get(i);
                    if (parameterMapping.getMode() != ParameterMode.OUT) {
                        String propertyName = parameterMapping.getProperty();
                        Object value;
                        if (this.boundSql.hasAdditionalParameter(propertyName)) {
                            value = this.boundSql.getAdditionalParameter(propertyName);
                        } else if (this.parameterObject == null) {
                            value = null;
                        } else if (this.typeHandlerRegistry.hasTypeHandler(this.parameterObject.getClass())) {
                            value = this.parameterObject;
                        } else {
                            MetaObject metaObject = this.configuration.newMetaObject(this.parameterObject);
                            value = metaObject.getValue(propertyName);
                        }
                        //获得对应的TypeHandler
                        TypeHandler typeHandler = parameterMapping.getTypeHandler();
                        JdbcType jdbcType = parameterMapping.getJdbcType();
                        if (value == null && jdbcType == null) {
                            jdbcType = this.configuration.getJdbcTypeForNull();
                        }
    
                        try {
                            //给Statement设置参数
                            typeHandler.setParameter(ps, i + 1, value, jdbcType);
                        } catch (TypeException var10) {
                            throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + var10, var10);
                        } catch (SQLException var11) {
                            throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + var11, var11);
                        }
                    }
                }
            }
    
        }
    }

    StatementHandler设置

    可选类型

    public enum StatementType {
      STATEMENT, PREPARED, CALLABLE
    }

    xml设置

    <select id="findAllStudents" resultMap="StudentResult" statementType="STATEMENT">
        SELECT * FROM STUDENTS
    </select>
  • 相关阅读:
    mysql-5-aggregation
    mysql-4-functions
    mysql-3-orderby
    技术之心 | 云信和TA们携手打响防疫战
    疫情下的传统商企自救|4个Tips搭建销量过亿直播间
    那些2019年会爆发的泛娱乐黑科技风口
    流量难、获客难、增长难?增长黑客思维“解救”B端业务
    【翻译】Facebook全面推出Watch Party,可多人线上同看直播视频
    深入浅出聊一聊Docker
    C++写日志方法调试
  • 原文地址:https://www.cnblogs.com/LQBlog/p/10682987.html
Copyright © 2011-2022 走看看