debug重点方法标注:
将sql中的所有待填参数的类型和参数的类型做组合
org.apache.ibatis.builder.SqlSourceBuilder#parse
参数处理:通过sql中的参数“authorId,jdbcType=VARCHAR”解析jdbcType,java类型是通过参数类型解析的。因此如果sql中没有写jdbcType=VARCHAR,这里将解析不到jdbcType,所以查找typehandler时将只通过javaType查找
org.apache.ibatis.builder.SqlSourceBuilder.ParameterMappingTokenHandler#buildParameterMapping
处理结果:通过类型查找typeHandler
org.apache.ibatis.executor.resultset.ResultSetWrapper#getTypeHandler
获取typeHandler
org.apache.ibatis.type.TypeHandlerRegistry
封装resultMap,其中已经封装好了所使用的typeHandler,如果查询语句没有使用resultMap,这里封装时没有添加typehandler
org.apache.ibatis.builder.MapperBuilderAssistant#addMappedStatement(java.lang.String, org.apache.ibatis.mapping.SqlSource, org.apache.ibatis.mapping.StatementType, org.apache.ibatis.mapping.SqlCommandType, java.lang.Integer, java.lang.Integer, java.lang.String, java.lang.Class<?>, java.lang.String, java.lang.Class<?>, org.apache.ibatis.mapping.ResultSetType, boolean, boolean, boolean, org.apache.ibatis.executor.keygen.KeyGenerator, java.lang.String, java.lang.String, java.lang.String, org.apache.ibatis.scripting.LanguageDriver, java.lang.String)
总结:
mybatis sql的执行过程有sql的解析和结果集映射,这两个过程都使用了typehandler。
(1)sql解析:
sql解析时会将参数填充到sql中,此时会通过jdbcType和javaType来查找对应的typeHandler(如果sql中没有使用类似“jdbcType=BIGINT”,则无法获取该jdbcType,因此只能通过javaType去查找对应的typeHandler)。
例如sql如下:
update author
set author_id = #{authorId,jdbcType=VARCHAR},
author_name = #{authorName,jdbcType=VARCHAR},
content = #{content,jdbcType=VARCHAR}
where id = #{id,jdbcType=BIGINT};
jdbcType是通过sql中“jdbcType=BIGINT”来获取的,所以如果我们在写sql时如果不填写“jdbcType=BIGINT”,则sql解析时将无法获取该字段的jdbcType。javaType是通过参数的名字,通过反射获取该属性的类型的。
(2)结果集映射
结果集映射时分两种:使用ResultMap和不使用ResultMap
①使用ResultMap
<resultMap id="BaseResultMap" type="com.qunar.corp.demo.model.Author" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="author_id" property="authorId" jdbcType="VARCHAR" />
<result column="author_name" property="authorName" jdbcType="VARCHAR" />
<result column="content" property="content" jdbcType="VARCHAR" />
</resultMap>
如上述所示,如果使用ResultMap,则mybatis会根据其中的jdbcType和反射得到的java类型,来查找typeHandler。
②不使用ResultMap
例如sql如下:
<select id="selectByPrimaryKey" resultType="com.qunar.corp.demo.model.Author" parameterType="java.lang.Long" >
select
id, author_id, author_name, content
from author
where id = #{id,jdbcType=BIGINT}
</select>
这种情况下查询到结果集并映射到实体类时,无法获取到每个字段的jdbcType,而每个字段的javaType会通过反射获取到。然后通过javaType去查找typeHandler。
网友评论