当前位置:   article > 正文

Mybatis源码阅读的关键点_mybatis 源码 关注点

mybatis 源码 关注点
阅读Mybatis源码时,随手下关键点,以备以后查看
解析过程如下:
XMLConfigBuilder.mapperElement ===> configuration.addMappers(mapperPackage);
MapperAnnotationBuilder.parse 解析注解的入口
MapperAnnotationBuilder.parseStatement 解析Mapper中的每个方法,形成MappedStatement
MapperAnnotationBuilder.getSqlSourceFromAnnotations 获取注解中的SQL语句
XMLLanguageDriver.createSqlSource 解析注解中SQL语句,替换${...}占位符
PropertyParser.parse 解析语句中属性值(${...}占位符)
SqlSourceBuilder.parse 解析语句中数据值#{...}占位符

如果带IN查询SQL
@Select(value = { "<script>", "SELECT * FROM [USER] WHERE ID IN ", "<foreach item='item' index='index' collection='ids' open='(' separator=',' close=')'>", "${item}", "</foreach>", "</script>" })
@Results(value = { @Result(column = "user_name", property = "userName") })
public List<String> getUserNameByIds(@Param("ids") List<Integer> ids);
解析过程如下:
XMLLanguageDriver.createSqlSource 使用XPathParser解析
XMLScriptBuilder.parseScriptNode Xml方式解析
XMLScriptBuilder.nodeHandlers 和 NodeHandler接口实现Xml节点解析

map.put("trim", new TrimHandler());
map.put("where", new WhereHandler());
map.put("set", new SetHandler());
map.put("foreach", new ForEachHandler());
map.put("if", new IfHandler());
map.put("choose", new ChooseHandler());
map.put("when", new IfHandler());
map.put("otherwise", new OtherwiseHandler());
map.put("bind", new BindHandler());

2 解析mapper.xml
mapper有哪些节点:
cache-ref、cache、parameterMap、resultMap、sql、select|insert|update|delete


3 执行SQL Statement的过程
解析过程如下
DefaultSqlSession.selectOne/selectList/insert/delete... CRUD操作调用
CachingExecutor.query/update CRUD都会调用query/update方法
BoundSql.getBoundSql 解析SQL,填充数据
DynamicContext 是动态上下文,包括configuration和参数
GenericTokenParser解析SQL,替换SQL中的参数${...}
TextSqlNode.handleToken 核心方法

${...} 属性占位符,属于静态文本替换
#{...} sql参数占位符,替换为?号

<select id="getAllTask" parameterType="hashmap" resultType="com.suncht.model.Task">
select * from DAQ_TASK order by ${order} desc
</select>
${order} 是可以支持OGNL表达式
parameterType对应的是 TypeAliasRegistry预置的
parameterType如果是hashMap 或者 map, ${order}直接从map中获取填充。
如果不是map类型的, ${order}需要从对象反射获取,所以需要set/get;MetaObject类是Mybatis自带的对象反射机制。

Mybatis提供了9种动态sql标签trim|where|set|foreach|if|choose|when|otherwise|bind


DynamicSqlSource:SQL中带${...}、包含动态sql标签。
传递参数是map、对象,貌似不支持string\integer等,因为string/integer没有get/set
RawSqlSource:不带${...}和动态sql标签
传递参数是map、对象、string

传递参数parameterType问题:
(1)只有一个参数情况下,要注意传参类型问题
sql执行时,参数占位符#{...} 根据parameterType自动转换。

DynamicSqlSource:传递参数是map、对象,貌似不支持string\integer等,因为string/integer没有get/set
RawSqlSource:传递参数是map、对象、string/integer

比如:#{taskName}
mybatis先从参数获取值,再把值转换成parameterType类型
如果parameterType是对象A, 对象A必须有taskName的set/get属性,而且类型有一致
如果parameterType是 map,转换成map
如果parameterType是string/integer,则需要考虑DynamicSqlSource、RawSqlSource

建议:使用对象或map,类型要保持一致
(2)多个参数情况下
一般使用对象或map

(3)参数值为null的情况
需要在SQL的参数占位符注明jdbcType,比如#{id:VARCHAR}
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/650473
推荐阅读
相关标签
  

闽ICP备14008679号