mybatis-spring.jar 是mybatis与spring的整合,使用mybatis可以完成访问数据库的操作,通过SqlSession可以拿到Mapper的对象,
SqlSession维护了Configuration对象,缓存了knowMappers,class——MapperProxyFactory的映射,所以如果单纯的使用mybatis可以直接
sqlSession.getMapper手动获取。
一:单纯使用mybatis的方法
1:注册,sqlSessionFactoryBuildler或者SqlSessionFactoryBean创建SqlSessionFactory的时候,会解析mybatis-config.xml,最后一步
会解析mapper.xml文件,其中解析命名空间的时候,会将类型与动态代理工厂绑定。
数据源配置:
##数据源配置 jdbc.driverClass=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/study jdbc.username=root jdbc.password=root
mybatis-config.xml中的配置数据源以及mapper.xml文件
<environments default="development">
<!-- 配置环境,id:环境的唯一标识 -->
<environment id="development">
<!-- 事务管理器,type:使用jdbc的事务管理器 -->
<transactionManager type="JDBC" />
<!-- 数据源,type:池类型的数据源 -->
<dataSource type="POOLED">
<!-- 配置连接信息 -->
<property name="driver" value="${jdbc.driverClass}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 配置映射文件:用来配置sql语句和结果集类型等 -->
<mappers>
<mapper resource="UserMapper.xml" />
</mappers>
解析命名空间并注册绑定:



2:使用的时候直接通过SqlSession.getMapper(class)获取Mapper对象(代理对象)




测试代码:

可以正常查询结果:

二:与spring的整合是怎么实现的
在spring-context.xml的文件中加载配置,配置数据源bean,使用SqlSessionFactoryBean创建SqlSessionFactroy
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:application.properties" />
<!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClass}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 指定数据源和配置文件路径 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:UserMapper.xml"></property>
</bean>
<!-- 配置单个mapper接口的映射器 -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.example.mybatis.mapper.UserMapper"></property>
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<!--<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.mybatis.mapper"></property>
</bean>-->
</beans>
这里创建SqlSessionFactory对象的过程与mybatis直接创建有点区别,mybatis是通过SqlSessionFactoryBuilder创建,这里是FactoryBean

这个类实现了FactoryBean接口,InitializingBean接口

重写afterPropertiesSet,在这里解析mybatis-config.xml文件,生成Configuration对象,封装到SqlSessionFactory中返回。




解析mapper.xml文件,解析过程可以参考前面章节的mybatis-config.xml的解析。

上面是解析mapper.xml配置文件,将解析后的信息封装到configuration中,下面看一下如何整合绑定的

mybatis-spring中有个比较重要的类MapperFactoryBean,实例化userMapper对象(代理),是通过创建MapperFactoryBean
这个bean元素下面有两个子元素,一个是mapperInterface,代理的接口,一个是sqlSessionFactory,在创建Bean对象的时候会设置属性


设置sqlSessionFactory的时候实际上是把sqlSessionFactory封装到了sqlSessionTemplate中

这个类实现了FactoryBean接口,所以实际上getBean得到的对象是getObject返回的代理对象

这里的sqlSession就是上面再解析自定义标签bean的时候,实例化userMapper时,设置SqlSessionFactory的时候创建的

后面的过程就是mybatis中的逻辑,根据类type获取Mapper代理工厂,然后newInstance创建代理对象。


来看一下创建sqlSessionTemplate的过程,所有的增删改查的动作都会为他给sqlSessionProxy代理来完成

代理增强:

每次执行增删改查操作都会创建一个SqlSession会话
这是单个mapper和spring的整合,如果mapper比较多,使用这种配置的方式就比较繁琐了
所以扫描的方式相比效率就搞多了,下面我们来看一下扫描的逻辑:
配置如下:
把上面配置的单个的mapper注释掉,配置通过路径扫描来创建mapper代理:

首先来分析一下这个类:

实现了四个接口,我们来复习一下这四个接口的作用:
BeanDefinitionRegistryPostProcessor,这个接口是在spring标准的BeanDefinition注册完成后,可以自定义BeanDefinition完成注册或者修改BeanDefinition的信息,也可以直接注册对象,是在BeanDefinition注册时期
InitializingBean接口,是bean实例化完成后的初始化方法,是在spring的aware接口初始化之后调用的
ApplicationContextAware接口:是在bean实例化完成后,初始化完成BeanNameAware等3个之后,使用BeanPostProcessor完成的初始化
BeanNameAware接口:是在bean实例化后,初始化的时候调用的
初始化顺序:BeanNameAware 早于 ApplicationContextAware 早于 InitializingBean


扫描并注册BeanDefinition对象,然后修改BeanDefinition对象的属性

具体扫描的逻辑:

具体设置属性信息,就是将扫描并注册的BeanDefinition,修改属性BeanClass 为MapperFactoryBean


这样扫描的BeanDefinition对象 ,实例化的时候都是MapperFactoryBean的实例了,不需要每个mapper都去配置xml了。
原文:https://www.cnblogs.com/warrior4236/p/13234197.html