StatementHandler 是一个非常核心接口,不仅要创建合适statement对象,再将参数放到statement对象中,执行sql,处理结果集.可以说这些步骤都是在statementHandle中
实现的,接下来咱们跟着源码一起来分析,还是以查询为例,接着上期的selectOne分析
再来看一下statement的uml图
接下来,我们需要设置参数到sql中了,JDBC 提供了三种 Statement 接口,分别是 Statement、PreparedStatement 和 CallableStatement。他们的uml图为:
statement:提供执行的sql语句
PreparedStatement:对输入参数执行动态替换,也就是将之前的?替换为具体的参数
CallableStatement:用于保存存储过程输出的结果
我们来来分析PreparedStatement
statement创建就是这样,重点看下参数是怎样设置进去的
我们来执行一条根据主键查询的sql语句,然后debug运行,看看参数如何设置进去的
每一个?都会在parameterMappings集合中生成一个对象属性,执行完之后,一条正正的sql就形成了
当我们执行完sql后就要开始处理查询结果了结果集的处理工作由结果集处理器 ResultSetHandler 执行。ResultSetHandler 是一个接口,它只有一个实现类 DefaultResultSetHandler。结果集的处理入口方法是 handleResultSets,下面来看一下该方法的实现。
这里注意啊一下,resultHandle是一个接口,我们可以实现自己的类,用来自定义结果集,map,list等等
参数处理器负责为ParameterHandler的sql语句参数动态赋值。
这个接口中只有两个方法:
getParameterObject 方法用于读取参数。
setParameters用于对ParameterHandler的参数赋值。
参数处理器对象时在创建StatementHandler对象时同时被创建的,由configuration对象负责创建。
创建时传入三个对象:mappedStatement(执行SQL对应的配置信息)、parameterObject、boundSql。
注意:一个BoundSql对象,代表了SQL语句的一次执行,而SqlSource对象的责任就是根据传入的参数对象动态计算出这个BoundSql,也就是说Mapper文件中的节点的计算是由SqlSource对象完成的。SqlSource最常用是实现类是DynamicSqlSource。
看看上述的实参10是如何添加到对应的SQL语句中的
在MyBatis中,使用动态代理模式,当dao.findByDeptNo(10)将要执行的时候,会被JVM进行拦截交给MyBatis中的代理实现类MapperProxy中的invoke方法。
最后交给ParameterHandler中setParameter方法,将参数交给对应占位符。
读取ParameterObject参数对象,然后用typeHandler对参数进行设置,而typeHandler里面需要对jdbcType和javaType进行处理,设置参数。所以使用TypeHandler的时候完全可以控制如何设置SQL参数。
ResultSetHandler接口主要负责两件事:
对于支持自动生成主键的数据库(如SQLServer),可以采用以下方式:
<insert
id="xxx"
parameterType="yyy"
useGeneratedKeys="true"
keyProperty="id">
....
</insert>
对于不支持自动生成主键(如Oracle),可以采用以下方式:
<insert
id="xxx"
parameterType="yyy">
<selectKey
keyProperty="id"
resultType="long"
order="BEFORE">
select
my_seq.nextval
from
dual
</selectKey>
....
</insert>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)