mybatis源码分析之spring加载mapper.xml文件原理解析

首先我们来看看mapper.xml文件的加载方式

第一种:基于mapper接口类具体路径配置

这种情况下,如果是非注解模式的话xml配置文件必须和这个类在同一级目录,且与Mapper类同名。项目结构类似

第二种:基于mapper类所在包的package路径配置

  

其实这算是第一种的一个变种。一个配置mapper类,每次新加删除比较麻烦,直接扫描mapper类所在包。项目结构类似

第三种:把 Mapper 的xml配置文件单独放置到 resources 中

和Mapper 类分开了,mapper接口位置还保持不动

但是mapper.xml被移动到了resources目录

第四种:使用spring配置加载mapper配置

可以看到,是往sqlsessionfactory中注入一系列的属性值。

(以上文章摘抄于https://blog.csdn.net/tanga842428/article/details/79285957,感谢博主的分享)

通过上面的四种配置方式,我们可以看到,mybatis有个默认潜规则:mapper接口类的名字和mapper.xml的名字是一致的。

基于上面的四种配置,可以引申出很多其他形式的配置,比如使用注解,基于实现原理再实现一遍,你就可开源xxx-mybatis-boot-start.jar类。小编们就是基于第四种实现原理,实现类一套,源码如下:

其中res1 和res2使用一个即可。由于项目架构的性质,我们使用了两个(当然还可以更多,因为mapperlocation是数组)。

铺垫做完了,我们开始今天的主题《mybatis源码分析之mapper.xml文件加载原理解析》

分析源码,关键是找对入口。首先我们来看下setMapperLocations方法的作用(resource对象传入的已经是根据正则表达式匹配到的各个xml文件了

“Set locations of MyBatis mapper files that are going to be merged into the {@code SqlSessionFactory}configuration at runtime.”。大概意思是讲:在系统启动时,这些mapper配置文件会被合并初始化到SqlSessionFactory。接下来我们来看下SqlSessionFactory初始化做了些什么。

本文代码的切入点是bean.getObject()。一路跟踪(bean.getObject()->afterPropertiesSet()->buildSqlSessionFactory()),并会发现,真正做事的是buildSqlSessionFactory(),其作用就是创建一个SqlSessionFactory实例并返回。

该方法源码比较长,不再贴源码,只解释下里面关键名词

configuration 、configLocation: mybatis配置文件,两者只会二选一加载,例如上面示例中的mybatis-config.xml

objectFactory mybatis对象工厂(没用过)

objectWrapperFactory mybatis对象包装类工厂(没用过)

vfs mybatis虚拟文件系统,在应用服务内,提供一个非常简单的方式访问资源(没用过)

            typeAliases 类型别名

            typeHandlers 类型处理器

            typeAliasesPackage 类型别名包路径

plugins 插件类(后续会讲)

typeHandlers 类型处理器

typeHandlersPackage 类型处理器包路径

databaseIdProvider (官方描述MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。 如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃)

mapperLocations mapper文件地址


解析一个个mapper.xml文件,放入config,然后返回。下面看看XMLMapperBuilder是怎么解析的

第一步:new XMLMapperBuilder构造类,把xml文件解析成document。xml解析方式

第二步:xmlMapperBuilder.parse()。分析xml中的每个node,转化为对象。下面着重介绍这步

configurationElement方法负责解析mapper节点下的各个子节点,并放入configuration中。回想一下mapper.xml的结构。

我们重点介绍下buildStatementFromContext(context.evalNodes("select|insert|update|delete"))方法,该方法是解析增删改查语句生成MappedStatement,并放入configuration的mappedStatements中,解析失败的放入incompleteStatements失败列表。 注意mappedStatements是一个map,value为MappedStatement,key为什么形式呢。举个例子:如果你的接口类(之前的namespace)是com.org.userMapper,节点id为selectOne的话,该map的id为com.org.userMapper.selectOne。这样保证了不同接口类,可以使用相同名字

至此,mapper.xml的解析完成,我们在看看收尾工作是怎么做的

 

解析失败的记录会死循环处理,那么总的有地方触发处理这处理失败的语句。触发方法如下

该方法注释写到,当所有的mapper.xml文件加载完成,推荐只调用一次该方法,处理这些之前失败的记录。

于是查看该方法的调用栈得到

系统启动完成后,会通过event机制调用一次

 作者也玩公众号,欢迎关注《JAVA之庖丁解牛》

我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1xmq4bipwe3yf

Spring Boot是一个快速开发的框架,提供了很多方便的工具,其中包括Mybatis框架。在使用Mybatis框架时,需要将Mapper.xml文件加载到应用程序中。 在Spring Boot中,可以使用@MapperScan注解将Mapper接口的包路径配置到扫描器中,然后使用@Mapper注解将Mapper接口注入到IOC容器中。但是,这种方式只会自动扫描Mapper接口,对于Mapper.xml文件需要手动进行配置。 首先,需要在application.properties或application.yml文件中配置Mapper.xml文件的路径,例如: mybatis.mapper-locations=classpath:mapper/*.xml 然后,需要创建SqlSessionFactoryBean并为其设置DataSource和Mapper.xml文件的位置: @Configuration public class MybatisConfig { @Value("${mybatis.mapper-locations}") private String mapperLocations; @Autowired private DataSource dataSource; @Bean public SqlSessionFactoryBean sqlSessionFactory() throws Exception { SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); sessionFactory.setDataSource(dataSource); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(mapperLocations)); return sessionFactory; } } 在创建完SqlSessionFactoryBean后,需要在Mapper接口中使用@Mapper注解,并通过@Autowired注入SqlSessionFactoryBean,例如: @Mapper public interface UserMapper { @Autowired SqlSessionFactory sqlSessionFactory; // ... } 最后,在需要使用Mapper接口的地方,可以直接将Mapper接口注入到Spring Bean中,并使用@Autowired注入即可,例如: @RestController public class UserController { @Autowired private UserMapper userMapper; // ... } 通过这种方式,就可以在Spring Boot中方便地加载Mapper.xml文件,并使用Mybatis框架完成相应的数据操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值