- 浏览: 981389 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
上一篇文章:我们说过DefaultSqlSession,DefaultSqlSessionFactory根据执行器类型,事务级别,是否提交等信息,来构建执行器Executor,然后根据执行器和configuration构建SqlSession,默认为DefaultSqlSession,从DefaultSqlSession的类信息方法来看,DefaultSqlSession的查询则委托给executor的query,插入,更新,删除,则委托给executor的update,提交,回滚,清除缓存,刷新Statement,关闭SqlSession,都是委托给Executor的相应方法。这一节节我们来Executor
//执行器的构建
//根据数据源,事务级别,是否自动提交,创建执行器
//Configuration
从上面configuration的创建执行器方法,可以看出执行器有BatchExecutor,ReuseExecutor,SimpleExecutor
根据执行器类型,创建执行器,如果缓存启用,则包装executor为CachingExecutor;
//BatchExecutor
//SimpleExecutor
//CachingExecutor
从上可以看出CachingExecutor是SimpleExecutor,BatchExecutor等执行器代理执行器;
事务的获取,清除缓存,更新,查询操作实际上,是调用Executor的相应方法。SimpleExecutor,
BatchExecutor为实际执行器,继承BatchExecutor;
下面根据DefaultSqlSession,来看执行器的query,update,提交,回滚,清除缓存,刷新Statement,
关闭SqlSession
先来看SqlSession
代理执行器调用实际执行器BatchExecutor,ReuseExecutor,SimpleExecutor的query的方法
//CachingExecutor
//查询
查看BatchExecutor,ReuseExecutor,SimpleExecutor的query的方法,实际上是在BaseExecutor
//BaseExecutor
这里我们来看一下SimpleExecutor
//SimpleExecutor
//构造StatementHandler
//configuration
//RoutingStatementHandler
从RoutingStatementHandler可以看出,更新,查询,预编译都是通过代理StatementHandler,具体根据StatementType创建对应的StatementHandler,SimpleStatementHandler,PreparedStatementHandler,CallableStatementHandler
//获取Statement
//预编译
实际为RoutingStatementHandler,通过本地代理,预编译Statement,
我们来看statement实例化:
//PreparedStatementHandler,这里我们来看PreparedStatementHandler的实例化
我们再看一下
//CallableStatementHandler
从上面可以看出构造StatementHandler,实际上为RoutingStatementHandler,
RoutingStatementHandler更新,查询,预编译都是通过代理StatementHandler,具体根据StatementType创建对应的StatementHandler,SimpleStatementHandler,
PreparedStatementHandler,CallableStatementHandler,
由具体的StatementHandler,创建Statement
//参数设置
//PreparedStatementHandler
parameterHandler在BaseStatementHandler中
来看一下
//configuration创建ParameterHandler
//XMLLanguageDriver
//DefaultParameterHandler
//BaseTypeHandler
BaseTypeHandler的子类有Integer,Float,Double,Boolean,Day,TimeStamp,Clob,StringTypeHandler
这里我们来看StringTypeHandler
从上面可以看出,参数初始化实际上,是通过ParameterHandler来处理,ParameterHandler默认为DefaultParameterHandler,
DefaultParameterHandler初始化参数实际上,
是从boundSql获取statement参数映射parameterMappings,遍历parameterMappings
根据具体的parameterMapping,从parameterMapping获取TypeHandler
(Integer,Float,Double,Boolean,Day,TimeStamp,Clob,StringTypeHandler)
;最后由TypeHandler,去设置statement参数
//执行查询
l
//PreparedStatementHandler
//CallableStatementHandler
//关闭statement
//BaseStatementHandler
总结:
Sqlsession查询,通过CachingExecutor代理,CachingExecutor是SimpleExecutor,BatchExecutor等执行器代理执行器;
事务的获取,清除缓存,更新,查询操作实际上,是调用Executor的相应方法。SimpleExecutor,BatchExecutor为实际执行器,继承BatchExecutor。SimpleExecutor查询,如果有缓存,则利用缓存,没有则用从数据库中查询,查询过程,构造StatementHandler,获取Statement,执行查询,关闭statement。
//执行器的构建
//根据数据源,事务级别,是否自动提交,创建执行器
org.apache.ibatis.executor.Executor executor = configuration.newExecutor(tx, execType, autoCommit);
//Configuration
public Executor newExecutor(Transaction transaction, ExecutorType executorType, boolean autoCommit) { executorType = executorType != null ? executorType : defaultExecutorType; executorType = executorType != null ? executorType : ExecutorType.SIMPLE; Executor executor; if(ExecutorType.BATCH == executorType) executor = new BatchExecutor(this, transaction); else if(ExecutorType.REUSE == executorType) executor = new ReuseExecutor(this, transaction); else executor = new SimpleExecutor(this, transaction); if(cacheEnabled) executor = new CachingExecutor(executor, autoCommit); //将执行器插入到拦截器链中 executor = (Executor)interceptorChain.pluginAll(executor); return executor; }
从上面configuration的创建执行器方法,可以看出执行器有BatchExecutor,ReuseExecutor,SimpleExecutor
根据执行器类型,创建执行器,如果缓存启用,则包装executor为CachingExecutor;
//BatchExecutor
public class BatchExecutor extends BaseExecutor { public static final int BATCH_UPDATE_RETURN_VALUE = -2147482646; private final List statementList = new ArrayList(); private final List batchResultList = new ArrayList(); private String currentSql; private MappedStatement currentStatement; public BatchExecutor(Configuration configuration, Transaction transaction) { super(configuration, transaction); } }
//SimpleExecutor
public class SimpleExecutor extends BaseExecutor { public SimpleExecutor(Configuration configuration, Transaction transaction) { super(configuration, transaction); } }
//CachingExecutor
public class CachingExecutor implements Executor { private Executor _flddelegate; private boolean autoCommit; private TransactionalCacheManager tcm; private boolean dirty; public CachingExecutor(Executor delegate) { this(delegate, false); } public CachingExecutor(Executor delegate, boolean autoCommit) { tcm = new TransactionalCacheManager(); _flddelegate = delegate; this.autoCommit = autoCommit; } public Transaction getTransaction() { return _flddelegate.getTransaction(); } //更新 public int update(MappedStatement ms, Object parameterObject) throws SQLException { //刷新刷新 flushCacheIfRequired(ms); //调用代理更新 return _flddelegate.update(ms, parameterObject); } //查询 public List query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { BoundSql boundSql = ms.getBoundSql(parameterObject); CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql); return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); } //查询 public List query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { Cache cache; cache = ms.getCache(); if(cache == null) break MISSING_BLOCK_LABEL_183; flushCacheIfRequired(ms); if(!ms.isUseCache() || resultHandler != null) break MISSING_BLOCK_LABEL_183; ensureNoOutParams(ms, key, parameterObject, boundSql); if(dirty) break MISSING_BLOCK_LABEL_147; cache.getReadWriteLock().readLock().lock(); List list1; List cachedList = (List)cache.getObject(key); if(cachedList == null) break MISSING_BLOCK_LABEL_105; list1 = cachedList; cache.getReadWriteLock().readLock().unlock(); cache.getReadWriteLock().readLock().unlock(); cache.getReadWriteLock().readLock().unlock(); //调用代理查询 List list = _flddelegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); tcm.putObject(cache, key, list); return list; return _flddelegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); } public List flushStatements() throws SQLException { return _flddelegate.flushStatements(); } public void commit(boolean required) throws SQLException { _flddelegate.commit(required); tcm.commit(); dirty = false; } public void rollback(boolean required) throws SQLException { _flddelegate.rollback(required); dirty = false; if(required) tcm.rollback(); break MISSING_BLOCK_LABEL_43; if(required) tcm.rollback(); throw exception; } public void clearLocalCache() { _flddelegate.clearLocalCache(); } }
从上可以看出CachingExecutor是SimpleExecutor,BatchExecutor等执行器代理执行器;
事务的获取,清除缓存,更新,查询操作实际上,是调用Executor的相应方法。SimpleExecutor,
BatchExecutor为实际执行器,继承BatchExecutor;
下面根据DefaultSqlSession,来看执行器的query,update,提交,回滚,清除缓存,刷新Statement,
关闭SqlSession
public class DefaultSqlSession implements SqlSession { private Configuration configuration; private Executor executor; private boolean dirty; public DefaultSqlSession(Configuration configuration, Executor executor) { this.configuration = configuration; this.executor = executor; dirty = false; } //查询 public Object selectOne(String statement) { return selectOne(statement, null); } public Object selectOne(String statement, Object parameter) { List list = selectList(statement, parameter); if(list.size() == 1) return list.get(0); if(list.size() > 1) throw new TooManyResultsException((new StringBuilder()).append("Expected one result (or null) to be returned by selectOne(), but found: ").append(list.size()).toString()); else return null; } public List selectList(String statement) { return selectList(statement, null); } public List selectList(String statement, Object parameter) { return selectList(statement, parameter, RowBounds.DEFAULT); } public List selectList(String statement, Object parameter, RowBounds rowBounds) { List list; try { org.apache.ibatis.mapping.MappedStatement ms = configuration.getMappedStatement(statement); //调用executor的查询方法 List result = executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); list = result; } } //插入 public int insert(String statement) { return insert(statement, null); } public int insert(String statement, Object parameter) { //委托给update方法 return update(statement, parameter); } public int update(String statement) { return update(statement, null); } public int update(String statement, Object parameter) { int i; try { dirty = true; org.apache.ibatis.mapping.MappedStatement ms = configuration.getMappedStatement(statement); //委托给executor的update i = executor.update(ms, wrapCollection(parameter)); } } //删除 public int delete(String statement) { //委托给update return update(statement, null); } public int delete(String statement, Object parameter) { return update(statement, parameter); } //提交 public void commit() { commit(false); } public void commit(boolean force) { try { //委托executor的commit executor.commit(isCommitOrRollbackRequired(force)); dirty = false; } } //回滚 public void rollback() { rollback(false); } public void rollback(boolean force) { try { //委托executor的rollback executor.rollback(isCommitOrRollbackRequired(force)); dirty = false; } } //清除缓存 public void clearCache() { ////委托executor的clearLocalCache executor.clearLocalCache(); } //刷新Statements public List flushStatements() { List list; try { //委托executor的flushStatements list = executor.flushStatements(); } } //关闭SqlSession public void close() { //委托executor的close executor.close(isCommitOrRollbackRequired(false)); dirty = false; } }
先来看SqlSession
public List selectList(String statement, Object parameter, RowBounds rowBounds) { List list; try { org.apache.ibatis.mapping.MappedStatement ms = configuration.getMappedStatement(statement); //调用executor的查询方法 List result = executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); list = result; } }
代理执行器调用实际执行器BatchExecutor,ReuseExecutor,SimpleExecutor的query的方法
//CachingExecutor
//查询
public List query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { BoundSql boundSql = ms.getBoundSql(parameterObject); CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql); return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); } //查询 public List query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { List list = _flddelegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); tcm.putObject(cache, key, list); return list; return _flddelegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql); }
查看BatchExecutor,ReuseExecutor,SimpleExecutor的query的方法,实际上是在BaseExecutor
//BaseExecutor
public List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { BoundSql boundSql = ms.getBoundSql(parameter); CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql); //委托给query(ms, parameter, rowBounds, resultHandler, key, boundSql); return query(ms, parameter, rowBounds, resultHandler, key, boundSql); } public List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId()); if(closed) throw new ExecutorException("Executor was closed."); if(queryStack == 0 && ms.isFlushCacheRequired()) clearLocalCache(); List list; queryStack++; list = resultHandler != null ? null : (List)localCache.getObject(key); if(list != null) //从本地获取查询结果 handleLocallyCachedOutputParameters(ms, key, parameter, boundSql); else //从数据库查询结果 list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql); return list; } //从数据库查询结果 private List queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException { localCache.putObject(key, ExecutionPlaceholder.EXECUTION_PLACEHOLDER); //委托给doQuery List list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql); localCache.removeObject(key); break MISSING_BLOCK_LABEL_53; Exception exception; exception; localCache.removeObject(key); throw exception; localCache.putObject(key, list); if(ms.getStatementType() == StatementType.CALLABLE) localOutputParameterCache.putObject(key, parameter); return list; } //doQuery为抽象方法,待子类扩展 protected abstract List doQuery(MappedStatement mappedstatement, Object obj, RowBounds rowbounds, ResultHandler resulthandler, BoundSql boundsql) throws SQLException;
这里我们来看一下SimpleExecutor
//SimpleExecutor
public List doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { Statement stmt = null; List list; Configuration configuration = ms.getConfiguration(); //构造StatementHandler StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, rowBounds, resultHandler, boundSql); //获取Statement stmt = prepareStatement(handler, ms.getStatementLog()); //执行查询 list = handler.query(stmt, resultHandler); //关闭statement closeStatement(stmt); return list; Exception exception; exception; closeStatement(stmt); throw exception; }
//构造StatementHandler
StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, rowBounds, resultHandler, boundSql);
//configuration
public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { //创建RoutingStatementHandler StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql); //拦截器处理statementHandler, statementHandler = (StatementHandler)interceptorChain.pluginAll(statementHandler); return statementHandler; }
//RoutingStatementHandler
public class RoutingStatementHandler implements StatementHandler { private final StatementHandler _flddelegate; public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { static class _cls1 { static final int $SwitchMap$org$apache$ibatis$mapping$StatementType[]; static { $SwitchMap$org$apache$ibatis$mapping$StatementType = new int[StatementType.values().length]; try { $SwitchMap$org$apache$ibatis$mapping$StatementType[StatementType.STATEMENT.ordinal()] = 1; } catch(NoSuchFieldError ex) { } try { $SwitchMap$org$apache$ibatis$mapping$StatementType[StatementType.PREPARED.ordinal()] = 2; } catch(NoSuchFieldError ex) { } try { $SwitchMap$org$apache$ibatis$mapping$StatementType[StatementType.CALLABLE.ordinal()] = 3; } catch(NoSuchFieldError ex) { } } } //根据StatementType,创建对应的StatementHandler switch(_cls1..SwitchMap.org.apache.ibatis.mapping.StatementType[ms.getStatementType().ordinal()]) { case 1: // '\001' _flddelegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); break; case 2: // '\002' _flddelegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); break; case 3: // '\003' _flddelegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql); break; default: throw new ExecutorException((new StringBuilder()).append("Unknown statement type: ").append(ms.getStatementType()).toString()); } } public Statement prepare(Connection connection) throws SQLException { return _flddelegate.prepare(connection); } public void parameterize(Statement statement) throws SQLException { _flddelegate.parameterize(statement); } public void batch(Statement statement) throws SQLException { _flddelegate.batch(statement); } public int update(Statement statement) throws SQLException { return _flddelegate.update(statement); } public List query(Statement statement, ResultHandler resultHandler) throws SQLException { return _flddelegate.query(statement, resultHandler); } public BoundSql getBoundSql() { return _flddelegate.getBoundSql(); } public ParameterHandler getParameterHandler() { return _flddelegate.getParameterHandler(); } }
从RoutingStatementHandler可以看出,更新,查询,预编译都是通过代理StatementHandler,具体根据StatementType创建对应的StatementHandler,SimpleStatementHandler,PreparedStatementHandler,CallableStatementHandler
//获取Statement
stmt = prepareStatement(handler, ms.getStatementLog()); private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException { //获取连接,这里实际上调用的为BaseExector的getConnection,从执行器的事务管理器获取连接 java.sql.Connection connection = getConnection(statementLog); //预编译 Statement stmt = handler.prepare(connection); //参数设置 handler.parameterize(stmt); return stmt; }
//预编译
Statement stmt = handler.prepare(connection);
实际为RoutingStatementHandler,通过本地代理,预编译Statement,
public abstract class BaseStatementHandler implements StatementHandler { //获取PrepareStatement public Statement prepare(Connection connection) throws SQLException { protected final Configuration configuration; protected final ObjectFactory objectFactory; protected final TypeHandlerRegistry typeHandlerRegistry; protected final ResultSetHandler resultSetHandler; protected final ParameterHandler parameterHandler; protected final Executor executor; protected final MappedStatement mappedStatement; protected final RowBounds rowBounds; protected BoundSql boundSql; Statement statement; ErrorContext.instance().sql(boundSql.getSql()); statement = null; //实例化Statement statement = instantiateStatement(connection); setStatementTimeout(statement); setFetchSize(statement); return statement; } //带子类扩展 protected abstract Statement instantiateStatement(Connection connection) throws SQLException; //设置statement的超时时间 protected void setStatementTimeout(Statement stmt) throws SQLException { Integer timeout = mappedStatement.getTimeout(); Integer defaultTimeout = configuration.getDefaultStatementTimeout(); if(timeout != null) stmt.setQueryTimeout(timeout.intValue()); else if(defaultTimeout != null) stmt.setQueryTimeout(defaultTimeout.intValue()); } //设置statement的FetchSize protected void setFetchSize(Statement stmt) throws SQLException { Integer fetchSize = mappedStatement.getFetchSize(); if(fetchSize != null) stmt.setFetchSize(fetchSize.intValue()); } }
我们来看statement实例化:
//PreparedStatementHandler,这里我们来看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); } //实例化Statement protected Statement instantiateStatement(Connection connection) throws SQLException { //获取sql String sql = boundSql.getSql(); if(mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) { String keyColumnNames[] = mappedStatement.getKeyColumns(); if(keyColumnNames == null) return connection.prepareStatement(sql, 1); else //从connection返回PreparedStatement return connection.prepareStatement(sql, keyColumnNames); } if(mappedStatement.getResultSetType() != null) return connection.prepareStatement(sql, mappedStatement.getResultSetType().getValue(), 1007); else return connection.prepareStatement(sql); } }
我们再看一下
//CallableStatementHandler
public class CallableStatementHandler extends BaseStatementHandler { protected Statement instantiateStatement(Connection connection) throws SQLException { String sql = boundSql.getSql(); if(mappedStatement.getResultSetType() != null) return connection.prepareCall(sql, mappedStatement.getResultSetType().getValue(), 1007); else //从connection返回CallableStatement return connection.prepareCall(sql); } }
从上面可以看出构造StatementHandler,实际上为RoutingStatementHandler,
RoutingStatementHandler更新,查询,预编译都是通过代理StatementHandler,具体根据StatementType创建对应的StatementHandler,SimpleStatementHandler,
PreparedStatementHandler,CallableStatementHandler,
由具体的StatementHandler,创建Statement
//参数设置
handler.parameterize(stmt);
//PreparedStatementHandler
public void parameterize(Statement statement) throws SQLException { parameterHandler.setParameters((PreparedStatement)statement); }
parameterHandler在BaseStatementHandler中
public abstract class BaseStatementHandler implements StatementHandler { protected final Configuration configuration; protected final ObjectFactory objectFactory; protected final TypeHandlerRegistry typeHandlerRegistry; protected final ResultSetHandler resultSetHandler; protected final ParameterHandler parameterHandler; protected final Executor executor; protected final MappedStatement mappedStatement; protected final RowBounds rowBounds; protected BoundSql boundSql; protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { configuration = mappedStatement.getConfiguration(); this.executor = executor; this.mappedStatement = mappedStatement; this.rowBounds = rowBounds; typeHandlerRegistry = configuration.getTypeHandlerRegistry(); objectFactory = configuration.getObjectFactory(); if(boundSql == null) { generateKeys(parameterObject); boundSql = mappedStatement.getBoundSql(parameterObject); } this.boundSql = boundSql; //configuration创建ParameterHandler parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql); resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql); } }
来看一下
//configuration创建ParameterHandler
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) { //从mappedStatement获取LanguageDriver,创建ParameterHandler ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql); //拦截器链处理ParameterHandler parameterHandler = (ParameterHandler)interceptorChain.pluginAll(parameterHandler); return parameterHandler; }
//XMLLanguageDriver
public class XMLLanguageDriver implements LanguageDriver { public ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) { return new DefaultParameterHandler(mappedStatement, parameterObject, boundSql); }
//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; configuration = mappedStatement.getConfiguration(); typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry(); this.parameterObject = parameterObject; this.boundSql = boundSql; } //设置PreparedStatement的参数 public void setParameters(PreparedStatement ps) throws SQLException { ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId()); //从boundSql获取参数映射 List parameterMappings = boundSql.getParameterMappings(); if(parameterMappings != null) { MetaObject metaObject = parameterObject != null ? configuration.newMetaObject(parameterObject) : null; for(int i = 0; i < parameterMappings.size(); i++) { //获取parameterMapping ParameterMapping parameterMapping = (ParameterMapping)parameterMappings.get(i); if(parameterMapping.getMode() == ParameterMode.OUT) continue; String propertyName = parameterMapping.getProperty(); Object value; if(boundSql.hasAdditionalParameter(propertyName)) value = boundSql.getAdditionalParameter(propertyName); else if(parameterObject == null) value = null; else if(typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) value = parameterObject; else value = metaObject != null ? metaObject.getValue(propertyName) : null; //获取具体的TypeHandler TypeHandler typeHandler = parameterMapping.getTypeHandler(); if(typeHandler == null) throw new ExecutorException((new StringBuilder()).append("There was no TypeHandler found for parameter ").append(propertyName).append(" of statement ").append(mappedStatement.getId()).toString()); JdbcType jdbcType = parameterMapping.getJdbcType(); if(value == null && jdbcType == null) jdbcType = configuration.getJdbcTypeForNull(); //typeHandler设置PreparedStatement参数 typeHandler.setParameter(ps, i + 1, value, jdbcType); } } } }
//BaseTypeHandler
public abstract class BaseTypeHandler extends TypeReference implements TypeHandler { public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException { if(parameter == null) { if(jdbcType == null) throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters."); try { ps.setNull(i, jdbcType.TYPE_CODE); } } else { //设置参数 setNonNullParameter(ps, i, parameter, jdbcType); } } //待父类扩展 public abstract void setNonNullParameter(PreparedStatement preparedstatement, int i, Object obj, JdbcType jdbctype) throws SQLException; }
BaseTypeHandler的子类有Integer,Float,Double,Boolean,Day,TimeStamp,Clob,StringTypeHandler
这里我们来看StringTypeHandler
public class StringTypeHandler extends BaseTypeHandler { public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter); } }
从上面可以看出,参数初始化实际上,是通过ParameterHandler来处理,ParameterHandler默认为DefaultParameterHandler,
DefaultParameterHandler初始化参数实际上,
是从boundSql获取statement参数映射parameterMappings,遍历parameterMappings
根据具体的parameterMapping,从parameterMapping获取TypeHandler
(Integer,Float,Double,Boolean,Day,TimeStamp,Clob,StringTypeHandler)
;最后由TypeHandler,去设置statement参数
//执行查询
l
ist = handler.query(stmt, resultHandler);
//PreparedStatementHandler
public List query(Statement statement, ResultHandler resultHandler) throws SQLException { PreparedStatement ps = (PreparedStatement)statement; ps.execute(); return resultSetHandler.handleResultSets(ps); }
//CallableStatementHandler
public List query(Statement statement, ResultHandler resultHandler) throws SQLException { CallableStatement cs = (CallableStatement)statement; cs.execute(); List resultList = resultSetHandler.handleResultSets(cs); resultSetHandler.handleOutputParameters(cs); return resultList; }
//关闭statement
closeStatement(stmt);
//BaseStatementHandler
protected void closeStatement(Statement statement) { if(statement != null) try { statement.close(); } catch(SQLException e) { } }
总结:
Sqlsession查询,通过CachingExecutor代理,CachingExecutor是SimpleExecutor,BatchExecutor等执行器代理执行器;
事务的获取,清除缓存,更新,查询操作实际上,是调用Executor的相应方法。SimpleExecutor,BatchExecutor为实际执行器,继承BatchExecutor。SimpleExecutor查询,如果有缓存,则利用缓存,没有则用从数据库中查询,查询过程,构造StatementHandler,获取Statement,执行查询,关闭statement。
发表评论
-
Mybatis缓存实现
2016-12-07 10:36 979SqlSessionFactory初始化:http://don ... -
DefaultSqlSession第三讲-事务提交,回滚,关闭SqlSession,清除缓存
2016-11-20 11:07 5699上面两篇讲过query和update及flushStateme ... -
DefaultSqlSession第二讲-更新,刷新Statement
2016-11-20 11:06 628上一篇文章中,我们讲到DefaultSqlSession的查询 ... -
Mybatis的SqlSession解析
2016-11-20 11:02 2545在前文中,Mybatis使用教程中,有下面一段代码: Sql ... -
Mybatis的Reflector解析
2016-11-18 12:53 2160Mybatis的MetaObject解析:http://don ... -
Mybatis的MetaObject解析
2016-11-18 11:40 9577SqlSessionFactory初始化:http://don ... -
mybatis 动态标签语句的解析(BoundSql)
2016-10-30 09:48 5755SqlSessionFactory初始化:http://don ... -
Mybatis的Environment解析详解
2016-10-29 18:28 1992SqlSessionFactory初始化:http://don ... -
Mybatis 解析Mapper(class)
2016-10-26 11:44 3347SqlSessionFactory初始化:http://don ... -
Mybatis加载解析Mapper(xml)文件第二讲
2016-10-25 21:30 4784SqlSessionFactory初始化:http://don ... -
Mybatis加载解析Mapper(xml)文件第一讲
2016-10-25 16:51 6178SqlSessionFactory初始化:http://don ... -
SqlSessionFactory初始化
2016-10-20 15:38 2454mybatis 使用教程:http://donald-drap ... -
mybatis 使用教程
2016-10-14 09:03 908Myeclispe下mybatis generator的使 ... -
Spring+Mybatis多数据源的实现
2016-09-21 18:15 3094浅谈Spring事务隔离级别:http://www.cnblo ... -
mybaitis CDATA 防止字符被解析
2016-08-17 18:45 724在使用mybatis 时我们sql是写在xml 映射文件中,如 ... -
Myeclispe下mybatis generator的使用
2016-07-05 18:05 1376准备:下载附件包解压到myeclispe的dropins文件夹 ...
相关推荐
易语言DnsQuery解析DNS源码,DnsQuery解析DNS,DnsFlushResolverCache,DnsQuery_A1,DnsQuery_A,DnsQuery_W,DnsModifyRecordsInSet_A,DnsGetCacheDataTable,inet_addr,DnsRecordListFree,GetAddrInfo,LocalSize_DNS_...
易语言源码易语言DnsQuery解析DNS源码.rar 易语言源码易语言DnsQuery解析DNS源码.rar 易语言源码易语言DnsQuery解析DNS源码.rar 易语言源码易语言DnsQuery解析DNS源码.rar 易语言源码易语言DnsQuery解析DNS源码....
1. **发起查询**:程序通过调用DnsQuery函数,向DNS服务器发送一个查询请求,包含待解析的域名。 2. **构建DNS报文**:在请求中,DNS报文会包含DNS头、问题部分(包含查询的域名和类型)、以及可能的答案、权威记录...
DnsQuery解析DNS.rar
1. **数据源连接**:Power Query支持连接到多种数据源,包括Excel表格、数据库、文本/CSV文件、Web、SQL Server、Oracle、PDF等,允许用户轻松地从不同来源获取数据。 2. **数据预处理**:Power Query提供了丰富的...
pg_query_go, 使用PostgreSQL解析器解析和规范化SQL查询 pg_query_go 转到 https://github.com/lfittl/pg_query的版本。这个go库及其扩展使用实际的PostgreSQL服务器源解析SQL查询,并返回内部PostgreSQL解析树。请...
phpQuery是基于PHP开发的一个强大的网页解析库,它的设计灵感来源于JavaScript库jQuery,因此在使用上有着类似jQuery的语法风格,使得PHP开发者可以方便地在服务器端进行DOM操作,提取和修改HTML或XML文档内容。...
Power Query第一课模板
在这个“易语言DnsQuery解析DNS源码”中,我们主要探讨的是如何使用易语言来实现DNS查询功能。 DNS(Domain Name System)域名系统是互联网的一项核心服务,它将人类可读的域名转换为IP地址,从而实现网络的访问。...
- 获取元素内容:`$doc->find('h1')->text()`返回第一个h1元素的文本内容。 - 遍历元素集合:`foreach ($doc->find('img') as $img)`遍历所有的图片元素并进行操作。 - 修改元素属性:`$doc->find('a')->attr('href'...
$pageInt = $request->query->getInt('page', 1); // 输出或使用$page和$pageInt ... } ``` 这里,`$request->query`是一个`QueryBag`对象,它提供了`get()`和`getInt()`等方法来获取query参数。`get()`方法...
1. **快速解析**:`jurl`库设计时考虑了性能,它提供了快速的URL解析功能,可以高效地分解URL的各个组成部分,如协议、主机、端口、路径、查询参数等。 2. **UTF-8编码支持**:在处理URL时,字符编码是一个重要的...
比如,选择 class 为 "blkTop" 的第一个 `h1` 标签: ```php pq(".blkTop h1:eq(0)") ``` 4. **操作节点**:选取的元素可以通过各种方法进行操作。例如,获取 `html()` 内容或 `text()` 内容: ```php echo pq("....
2. **获取文本文件**:介绍如何使用Power Query读取和加载文本文件,这包括CSV、TXT等格式的数据,是数据导入的第一步。 3. **更改数据类型**:数据预处理的重要环节,Power Query提供了方便的工具来转换列的数据...
SAP ABAP Query 是 SAP 系统中一种用于创建自定义报表的强大工具,尤其适合那些对 SQL 不太熟悉或者没有数据库直接访问权限的用户。它提供了丰富的功能,使得开发人员可以构建复杂的数据查询,而无需编写大量的 ABAP...
SAP Query 报表是SAP系统中一种用于生成自定义报表的重要工具,它允许用户根据特定需求定制数据报告,从而提高数据分析和决策制定的效率。本操作手册旨在为SAP业务顾问和运维顾问提供关于如何分配和配置SAP Query...
Power Query是一种强大的数据预处理工具,由微软开发,旨在简化数据获取、清洗和转换的过程。它在Excel和Power BI Desktop中都有集成,极大地提升了用户处理和分析数据的能力。Power Query的核心是M语言(也称为...
Power Query是Excel中的一款强大数据查询和准备工具,它允许用户轻松地从各种数据源导入、清洗和转换数据。在Excel环境中,Power Query通常被称为“获取和转换”或M语言(用于公式和脚本的查询语言)。这款插件极大...
在SAP系统中,SAP Query是一个强大的工具,允许用户自定义报告以满足特定的数据查询需求。它提供了灵活的报表设计功能,使非编程背景的用户也能创建和修改查询。在某些情况下,我们可能希望在查询结果上添加交互性,...