标签:执行 error pre 封装对象 过程 lse ble cat ppi
StatementHandler解析
接口的作用是statement处理器,位于mybatis包的org.apache.ibatis.executor.statement目录下,源码如下:
1 package org.apache.ibatis.executor.statement; 2 3 import java.sql.Connection; 4 import java.sql.SQLException; 5 import java.sql.Statement; 6 import java.util.List; 7 8 import org.apache.ibatis.executor.parameter.ParameterHandler; 9 import org.apache.ibatis.mapping.BoundSql; 10 import org.apache.ibatis.session.ResultHandler; 11 12 public interface StatementHandler { 13 14 //sql预编译,构建Statement对象 15 Statement prepare(Connection connection) 16 throws SQLException; 17 18 //对prepare方法构建的预编译的SQL进行参数的设置 19 void parameterize(Statement statement) 20 throws SQLException; 21 22 //批量处理 23 void batch(Statement statement) 24 throws SQLException; 25 26 //执行预编译后的SQL--update语句 27 int update(Statement statement) 28 throws SQLException; 29 30 //执行预编译后的SQL--select语句 31 <E> List<E> query(Statement statement, ResultHandler resultHandler) 32 throws SQLException; 33 34 //获取SQL封装类BoundSql对象 35 BoundSql getBoundSql(); 36 37 //获取参数处理器对象 38 ParameterHandler getParameterHandler(); 39 40 }
可见StatementHandler的作用就是先通过prepare方法构建一个Statement对象,然后再调用其他方法对Statement对象进行处理
StatementHandler和Executor类似,StatementHandler也有两个实现类,BaseStatementHandler和RoutingStatementHandler
而BaseStatement又有三个子类实现它的抽象方法,下面再挨个分析,先看最简单的BaseStatementHandler
BaseStatementHandler解析
BaseStatementHandler是一个抽象父类,有三个子类继承于它,源码如下:
1 package org.apache.ibatis.executor.statement; 2 3 import java.sql.Connection; 4 import java.sql.SQLException; 5 import java.sql.Statement; 6 7 import org.apache.ibatis.executor.ErrorContext; 8 import org.apache.ibatis.executor.Executor; 9 import org.apache.ibatis.executor.ExecutorException; 10 import org.apache.ibatis.executor.keygen.KeyGenerator; 11 import org.apache.ibatis.executor.parameter.ParameterHandler; 12 import org.apache.ibatis.executor.resultset.ResultSetHandler; 13 import org.apache.ibatis.mapping.BoundSql; 14 import org.apache.ibatis.mapping.MappedStatement; 15 import org.apache.ibatis.reflection.factory.ObjectFactory; 16 import org.apache.ibatis.session.Configuration; 17 import org.apache.ibatis.session.ResultHandler; 18 import org.apache.ibatis.session.RowBounds; 19 import org.apache.ibatis.type.TypeHandlerRegistry; 20 21 public abstract class BaseStatementHandler implements StatementHandler { 22 23 protected final Configuration configuration;//全局配置 24 protected final ObjectFactory objectFactory;//对象工厂 25 protected final TypeHandlerRegistry typeHandlerRegistry; 26 protected final ResultSetHandler resultSetHandler;//结果集处理器 27 protected final ParameterHandler parameterHandler;//参数处理器 28 29 protected final Executor executor;//执行器 30 protected final MappedStatement mappedStatement;//mapper的SQL对象 31 protected final RowBounds rowBounds;//分页参数 32 33 protected BoundSql boundSql;//sql封装对象 34 35 //构造方法 36 protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { 37 this.configuration = mappedStatement.getConfiguration(); 38 this.executor = executor; 39 this.mappedStatement = mappedStatement; 40 this.rowBounds = rowBounds; 41 42 this.typeHandlerRegistry = configuration.getTypeHandlerRegistry(); 43 this.objectFactory = configuration.getObjectFactory(); 44 45 if (boundSql == null) { // issue #435, get the key before calculating the statement 46 generateKeys(parameterObject); 47 boundSql = mappedStatement.getBoundSql(parameterObject); 48 } 49 50 this.boundSql = boundSql; 51 52 this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql); 53 this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql); 54 } 55 56 //返回boundSql 57 public BoundSql getBoundSql() { 58 return boundSql; 59 } 60 61 //返回parameterHandler 62 public ParameterHandler getParameterHandler() { 63 return parameterHandler; 64 } 65 66 //预编译SQL语句 67 public Statement prepare(Connection connection) throws SQLException { 68 ErrorContext.instance().sql(boundSql.getSql()); 69 Statement statement = null; 70 try { 71 statement = instantiateStatement(connection);//调用抽象方法构建statement对象是,但是没有具体实现,而是交给其子类去实现 72 setStatementTimeout(statement);//设置statement超时时间 73 setFetchSize(statement);//设置statement的fetchSize 74 return statement; 75 } catch (SQLException e) { 76 closeStatement(statement); 77 throw e; 78 } catch (Exception e) { 79 closeStatement(statement); 80 throw new ExecutorException("Error preparing statement. Cause: " + e, e); 81 } 82 } 83 84 protected abstract Statement instantiateStatement(Connection connection) throws SQLException; 85 86 //给statement对象设置timeout 87 protected void setStatementTimeout(Statement stmt) throws SQLException { 88 Integer timeout = mappedStatement.getTimeout(); 89 Integer defaultTimeout = configuration.getDefaultStatementTimeout(); 90 if (timeout != null) { 91 stmt.setQueryTimeout(timeout); 92 } else if (defaultTimeout != null) { 93 stmt.setQueryTimeout(defaultTimeout); 94 } 95 } 96 97 //给statement对象设置fetchSize 98 protected void setFetchSize(Statement stmt) throws SQLException { 99 Integer fetchSize = mappedStatement.getFetchSize(); 100 if (fetchSize != null) { 101 stmt.setFetchSize(fetchSize); 102 } 103 } 104 105 //关闭statement 106 protected void closeStatement(Statement statement) { 107 try { 108 if (statement != null) { 109 statement.close(); 110 } 111 } catch (SQLException e) { 112 //ignore 113 } 114 } 115 116 //根据参数对象生成key 117 protected void generateKeys(Object parameter) { 118 KeyGenerator keyGenerator = mappedStatement.getKeyGenerator(); 119 ErrorContext.instance().store(); 120 keyGenerator.processBefore(executor, mappedStatement, null, parameter); 121 ErrorContext.instance().recall(); 122 } 123 124 }
可以看出BaseStatementHandler只是实现了StatementHandler的三个方法,其中getBoundSql和getParameterHandler方法只是返回了由构造方法初始化的boundSql和parameterHandler属性,
而prepare方法是用于构建Statement对象的,但是BaseStatementHandler只是调用了自身的抽象方法instantiateStatement来创建,然后对statement对象进行其他处理,但是创建的过程则没有实现,而是交给了其子类去实现。
BaseStatementHandler有三个子类,分别为:
SimpleStatememtHandler:最简单的StatementHandler,处理不带参数运行的SQL
PreparedStatementHandler:预处理Statement的handler,处理带参数允许的SQL
CallableStatementHandler:存储过程的Statement的handler,处理存储过程SQL
先来看最简单的SimpleStatementHandler,它继承于BaseStatementHandler,所以它需要实现StatementHandler的接口,还需要重写父类BaseStatementHandler的抽象方法,源码如下:
1 package org.apache.ibatis.executor.statement; 2 3 import java.sql.Connection; 4 import java.sql.ResultSet; 5 import java.sql.SQLException; 6 import java.sql.Statement; 7 import java.util.List; 8 9 import org.apache.ibatis.executor.Executor; 10 import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator; 11 import org.apache.ibatis.executor.keygen.KeyGenerator; 12 import org.apache.ibatis.executor.keygen.SelectKeyGenerator; 13 import org.apache.ibatis.mapping.BoundSql; 14 import org.apache.ibatis.mapping.MappedStatement; 15 import org.apache.ibatis.session.ResultHandler; 16 import org.apache.ibatis.session.RowBounds; 17 18 public class SimpleStatementHandler extends BaseStatementHandler { 19 20 //构造方法执行父类的构造方法 21 public SimpleStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { 22 super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql); 23 } 24 25 //执行update操作 26 public int update(Statement statement) 27 throws SQLException { 28 String sql = boundSql.getSql(); 29 Object parameterObject = boundSql.getParameterObject(); 30 KeyGenerator keyGenerator = mappedStatement.getKeyGenerator(); 31 int rows; 32 //最终都是执行statement的getUpdateCount方法 33 if (keyGenerator instanceof Jdbc3KeyGenerator) { 34 statement.execute(sql, Statement.RETURN_GENERATED_KEYS); 35 rows = statement.getUpdateCount(); 36 keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject); 37 } else if (keyGenerator instanceof SelectKeyGenerator) { 38 statement.execute(sql); 39 rows = statement.getUpdateCount(); 40 keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject); 41 } else { 42 statement.execute(sql); 43 rows = statement.getUpdateCount(); 44 } 45 return rows; 46 } 47 48 //给statement添加批量处理sql语句 49 public void batch(Statement statement) 50 throws SQLException { 51 String sql = boundSql.getSql(); 52 statement.addBatch(sql); 53 } 54 55 //执行查询语句 56 public <E> List<E> query(Statement statement, ResultHandler resultHandler) 57 throws SQLException { 58 String sql = boundSql.getSql(); 59 statement.execute(sql);//statement.execute方法执行sql语句 60 return resultSetHandler.<E>handleResultSets(statement); 61 } 62 63 //构造Statement对象 64 protected Statement instantiateStatement(Connection connection) throws SQLException { 65 //通过Connection来create一个Statement对象 66 if (mappedStatement.getResultSetType() != null) { 67 return connection.createStatement(mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY); 68 } else { 69 return connection.createStatement(); 70 } 71 } 72 73 //由于SimpleStatementHandler是处理没有参数的SQL,所以参数设置的方法无需任何处理 74 public void parameterize(Statement statement) throws SQLException { 75 // N/A 76 } 77 78 }
可以看出主要是通过Connection创建一个Statement对象,然后通过调用Statement的execute方法执行sql语句
再看下PreparedStatementHandler,源码如下
1 package org.apache.ibatis.executor.statement; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 import java.util.List; 9 10 import org.apache.ibatis.executor.Executor; 11 import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator; 12 import org.apache.ibatis.executor.keygen.KeyGenerator; 13 import org.apache.ibatis.mapping.BoundSql; 14 import org.apache.ibatis.mapping.MappedStatement; 15 import org.apache.ibatis.session.ResultHandler; 16 import org.apache.ibatis.session.RowBounds; 17 18 public class PreparedStatementHandler extends BaseStatementHandler { 19 20 //执行父类构造方法 21 public PreparedStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { 22 super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql); 23 } 24 25 //执行update操作 26 public int update(Statement statement) throws SQLException { 27 PreparedStatement ps = (PreparedStatement) statement; 28 ps.execute(); 29 int rows = ps.getUpdateCount(); 30 Object parameterObject = boundSql.getParameterObject(); 31 KeyGenerator keyGenerator = mappedStatement.getKeyGenerator(); 32 keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject); 33 return rows; 34 } 35 36 //给preparedStatement对象添加批量处理sql语句 37 public void batch(Statement statement) throws SQLException { 38 PreparedStatement ps = (PreparedStatement) statement; 39 ps.addBatch(); 40 } 41 42 //执行preparedStatement的查询语句 43 public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException { 44 PreparedStatement ps = (PreparedStatement) statement; 45 ps.execute(); 46 return resultSetHandler.<E> handleResultSets(ps); 47 } 48 49 //构建Statement的子类PreparedStatement对象 50 protected Statement instantiateStatement(Connection connection) throws SQLException { 51 String sql = boundSql.getSql(); 52 if (mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) { 53 String[] keyColumnNames = mappedStatement.getKeyColumns(); 54 if (keyColumnNames == null) { 55 return connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS); 56 } else { 57 return connection.prepareStatement(sql, keyColumnNames); 58 } 59 } else if (mappedStatement.getResultSetType() != null) { 60 return connection.prepareStatement(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY); 61 } else { 62 return connection.prepareStatement(sql); 63 } 64 } 65 66 //给Statement对象设置参数 67 public void parameterize(Statement statement) throws SQLException { 68 parameterHandler.setParameters((PreparedStatement) statement); 69 } 70 71 }
是
mybatis源码解析5---StatementHandler解析
标签:执行 error pre 封装对象 过程 lse ble cat ppi
原文地址:https://www.cnblogs.com/jackion5/p/9517882.html