Mybatis占位符#和$的区别?源码解读(mybatis预编译占位符)

  本篇文章为你整理了Mybatis占位符#和$的区别?源码解读(mybatis预编译占位符)的详细内容,包含有mysql占位符 mybatis预编译占位符 mybatis的占位符有哪些 mybatis#号和$区别 Mybatis占位符#和$的区别?源码解读,希望能帮助你了解 Mybatis占位符#和$的区别?源码解读。

  Mybatis 作为国内开发中常用到的半自动 orm 框架,相信大家都很熟悉,它提供了简单灵活的xml映射配置,方便开发人员编写简单、复杂SQL,在国内互联网公司使用众多。

  本文针对笔者日常开发中对 Mybatis 占位符 #{} 和 ${} 使用时机结合源码,思考总结而来

  Mybatis 版本 3.5.11

  Spring boot 版本 3.0.2

  mybatis-spring 版本 3.0.1

  github地址:https://github.com/wayn111, 欢迎大家关注,点个star

  一. 启动时,mybatis-spring 解析xml文件流程图

  Spring 项目启动时,mybatis-spring 自动初始化解析xml文件核心流程
 

  
 

  Mybatis 在 buildSqlSessionFactory() 会遍历所有 mapperLocations(xml文件) 调用 xmlMapperBuilder.parse()解析,源码如下
 

  
 

  在 parse() 方法中, Mybatis 通过 configurationElement(parser.evalNode("/mapper")) 方法解析xml文件中的各个标签

  

public class XMLMapperBuilder extends BaseBuilder {

 

   private final MapperBuilderAssistant builderAssistant;

   private final Map String, XNode sqlFragments;

   public void parse() {

   if (!configuration.isResourceLoaded(resource)) {

   // xml文件解析逻辑

   configurationElement(parser.evalNode("/mapper"));

   configuration.addLoadedResource(resource);

   bindMapperForNamespace();

   parsePendingResultMaps();

   parsePendingCacheRefs();

   parsePendingStatements();

  
try {

   // 解析xml文件内的namespace、cache-ref、cache、parameterMap、resultMap、sql、select、insert、update、delete等各种标签

   String namespace = context.getStringAttribute("namespace");

   if (namespace == null namespace.isEmpty()) {

   throw new BuilderException("Mappers namespace cannot be empty");

   builderAssistant.setCurrentNamespace(namespace);

   cacheRefElement(context.evalNode("cache-ref"));

   cacheElement(context.evalNode("cache"));

   parameterMapElement(context.evalNodes("/mapper/parameterMap"));

   resultMapElements(context.evalNodes("/mapper/resultMap"));

   sqlElement(context.evalNodes("/mapper/sql"));

   buildStatementFromContext(context.evalNodes("selectinsertupdatedelete"));

   } catch (Exception e) {

   throw new BuilderException("Error parsing Mapper XML. The XML location is " + resource + ". Cause: " + e, e);

  

 

  最后会把 namespace、cache-ref、cache、parameterMap、resultMap、select、insert、update、delete等标签内容解析结果放到 builderAssistant 对象中,将sql标签解析结果放到sqlFragments对象中,其中 由于 builderAssistant 对象会保存select、insert、update、delete标签内容解析结果我们对 builderAssistant 对象进行深入了解

  

public class MapperBuilderAssistant extends BaseBuilder {

 

  public abstract class BaseBuilder {

   protected final Configuration configuration;

  public class Configuration {

   protected final Map String, MappedStatement mappedStatements = new StrictMap MappedStatement ("Mapped Statements collection")

   .conflictMessageProducer((savedValue, targetValue) -

   ". please check " + savedValue.getResource() + " and " + targetValue.getResource());

   protected final Map String, Cache caches = new StrictMap ("Caches collection");

   protected final Map String, ResultMap resultMaps = new StrictMap ("Result Maps collection");

   protected final Map String, ParameterMap parameterMaps = new StrictMap ("Parameter Maps collection");

   protected final Map String, KeyGenerator keyGenerators = new StrictMap ("Key Generators collection");

   protected final Set String loadedResources = new HashSet ();

   protected final Map String, XNode sqlFragments = new StrictMap ("XML fragments parsed from previous mappers");

  

 

  builderAssistant 对象继承至 BaseBuilder,BaseBuilder 类中包含一个 configuration 对象属性, configuration 对象中会保存xml文件标签解析结果至自身对应属性mappedStatements、caches、resultMaps、sqlFragments。

  这里有个问题上面提到的sql标签结果会放到 XMLMapperBuilder 类的 sqlFragments 对象中,为什么 Configuration 类中也有个 sqlFragments 属性?

  这里回看上文 buildSqlSessionFactory() 方法最后
 

  
 

  原来 XMLMapperBuilder 类中的 sqlFragments 属性就来自Configuration类

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: