一、前言
继上一篇mybatis查询语句的背后,这一篇主要围绕着mybatis查询的后期操作,即跟数据库交互的时候。由于本人也是一边学习源码一边记录,内容难免有错误或不足之处,还望诸位指正,本文只可当参考作用。谨记!
二、分析
继上一篇博文的查询例子,mybatis在最后的查询最终会走SimpleExecutor类的doQuery方法,
@Override
publicListdoQuery(MappedStatementms,Objectparameter,RowBoundsrowBounds,ResultHandlerresultHandler,BoundSqlboundSql)throwsSQLException{
Statementstmt=null;
try{
Configurationconfiguration=ms.getConfiguration();
//这里也就是采用了策略模式(个人感觉有点像),实际的statementHandler为routingStatementHandler
StatementHandlerhandler=configuration.newStatementHandler(wrapper,ms,parameter,rowBounds,resultHandler,boundSql);
stmt=prepareStatement(handler,ms.getStatementLog());
//虽然是执行的routingStatementHandler.query,但返回结果的还是PreparedStatementHandler处理
returnhandler.query(stmt,resultHandler);
}finally{
closeStatement(stmt);
}
}
privateStatementprepareStatement(StatementHandlerhandler,LogstatementLog)throwsSQLException{
Statementstmt;
//使用了代理模式,也可以理解为对connection进行了一层包装,这里的作用就是加了log处理
Connectionconnection=getConnection(statementLog);
//进行预编译,即类似jdbc的sql,如select*fromuserwhereid=?
stmt=handler.prepare(connection,transaction.getTimeout());
//对执行查询的sql进行参数设置
handler.parameterize(stmt);
returnstmt;
}
关于handler.prepare的作用这里简单介绍下,不做代码分析。
会设置fetchSize,作用就是一次性从数据库抓取数据,好像默认值是10条,如果每次只抓取一条,则进行rs.next的时候,会再次查库。
如果是insert操作,并且数据库主键自增且还设置了可以返回主键,则会还做获取主键的操作。
先从设置参数说起,也就是handler.parameterize。先看下源码,具体位置在DefaultParameterHandler类里面
@Override
publicvoidsetParameters(PreparedStatementps){
ErrorContext.instance().activity("settingparameters").object(mappedStatement.getParameterMap().getId());
//获取配置文件里面的sql参数信息,如sql为select*fromuserwhereid=#{userId,jdbcType=INTEGER}
//ParameterMapping记录了参数名也就是userId,还有记录了对应的jdbc类型,还有对应的javaType等等,具体可以debug看下
ListparameterMappings=boundSql.getParameterMappings();
if(parameterMappings!=null){
for(inti=0;i
对于上述代码中的一部分这里负责将parameterObject的里面的值整出来(也就是传入的参数),如果参数是map结构,就从map里面取值,如果不是,如单个非javabean参数,则直接取值,如果是单个javabean,则通过metaObject类转换成一个BeanWrapper,进行取值
这段代码也就负责对预编译后的sql设置参数,这里逻辑主要是围绕以下步骤进行得,
获取参数名,获取参数值,获取参数类型,然后做进行设值操作
/**
*mybatis数据处理有单结果集和多结果集处理,一般多结果集出现存储过程中,如果存储过程中写了两条select语句,如
*select*fromuser,select*fromclasses这种情况这里不做介绍,因为本人用的不多,理解的也不是很透彻。
*这里不多做介绍,这里只针对简单映射做一个大概介绍
*
*/
publicList