Mybatis3源码分析(11)-Sql解析执行-BoundSql的加载-1

本文深入探讨Mybatis的Sql解析执行过程,通过DefaultSqlSession.selectList方法,分析BoundSql类及其构造,包括MappedStatement.getBoundSql()和DynamicSqlSource.getBoundSql()方法。详细讲解DynamicContext动态上下文的创建,以及SqlSource与SqlNode如何协同工作,如StaticTextSqlNode、TextSqlNode和IfSqlNode的apply()方法在动态SQL解析中的作用。
摘要由CSDN通过智能技术生成

整理完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(
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值