整理完SqlSession和Executor的关系之后,接下来看看一条sql是怎么被解析执行的。
如下例:
public static void queryUser(SqlSessionFactory sqlSessionFactory)
{
SqlSession sqlSession=sqlSessionFactory.openSession();
try
{
Map<String,Object> param=new HashMap<>();
param.put("userId", "21458594739");
//sqlSession.selectList方法就是要详细分析的方法
List<User> list=sqlSession.selectList("com.ashan.user.selectUserDetail", param);
System.out.println(list);
sqlSession.commit();
}
catch(Exception e)
{
sqlSession.rollback();
}
finally
{
sqlSession.close();
}
}
<resultMap type="com.ashan.mybatis.User" id="detailUserResultMap">
<constructor>
<idArg column="user_id" javaType="String"/>
<arg column="user_name"/>
</constructor>
<result property="password" column="user_pwd" />
<result property="type" column="user_type" javaType="com.ashan.mybatis.UserType"
typeHandler="com.ashan.mybatis.UserTypeHandler"/>
<result property="svcnum" column="svc_num" />
<association property="cust" javaType="com.ashan.mybatis.Cust">
<id property="id" column="cust_id"/>
<result property="custname" column="cust_name"/>
<result property="certNo" column="cert_no"/>
</association>
<collection property="accts" ofType="com.ashan.mybatis.Acct">
<id property="id" column="acct_id" />
<result property="payName" column="pay_name"/>
<result property="bankNo" column="bank_no"/>
</collection>
</resultMap>
<select id="selectUserDetail" resultMap="detailUserResultMap">
<![CDATA[
select user_id,user_name,user_type,cust_id
from tf_f_user a
where a.user_id=#${userId}
]]>
</select>
DefaultSqlSession.selectList方法
public <E> List<E> selectList(String statement, Object parameter) {
//RowBounds表示查询的范围,一般在分页时用到
return this.selectList(statement, parameter, RowBounds.DEFAULT);
}
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
try {
//从Configuration获取一个MappedStatement配置
MappedStatement ms = configuration.getMappedStatement(statement);
//直接调用executor.query()方法
List<E> result = executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
return result;
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
从上可以看到sqlSession.selectList方法非常简单,他是用executor来完成查询的。再看看BaseExecutor对查询的实现:
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
//获取一个BoundSql,这个BoundSql的获取过程就是本节要详细讨论的
BoundSql boundSql = ms.getBoundSql(parameter);
CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);
return query(