正文
(十四)mybatis 和 spring 整合
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
flowchart 箭头图标 勿删
目录
- 整合思想
- 整合步骤
- 整合之后原始 dao 开发
- 整合之后 Mapper 代理开发
- 总结
整合思想
-
让
spring
管理
sqlSessionFactory
,使用
单例模式
创建该对象 ;
-
根据
sqlSessionFactory
创建
sqlsession
,这一步由
mybatis
和
spring
整合 以后,自动完成,不需要我们配置 ;
-
Mapper
接口的代理对象 ,由
spring
管理这些代理对象 ;
整合步骤
-
导包
导入
spring
、
mybatis
的包
导入
mybatis-spring
整合包 ;
-
搭建工程目录
需要注意的一点,就是在创建包的时候,为
mybatis
、
spring
都创建各自的配置文件包,便于管理 ;
-
导入
spring
、
mybatis
的配置文件
其中注意,
mybatis
的配置文件中的
environments
标签的内容在和
spring
整合以后,就被废弃了,也就是不再起作用了;
也就是
数据源
、
事务
,最后都由
spring
进行管理了 ;
废弃的
environments
标签内容 :
<!--当和 spring 整合以后,environments 配置将废除-->
<environments default="development">
<environment id="development">
<!--事务管理,暂时有mybatis管-->
<transactionManager type="JDBC"/>
<!--数据源 暂时也由 mybatis 管理,以后都由 spring 来管理-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
-
在
spring
中管理
sqlSessionFactory
sqlSessionFactory
不是我们在
mybatis
中使用的那个接口,而是在
mybatis-spring
SqlSessionFactoryBean
;
SqlSessionFactoryBean
类部分源码:
public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
private static final Log LOGGER = LogFactory.getLog(SqlSessionFactoryBean.class);
// 读取mybatis配置文件使用的资源流
private Resource configLocation;
.....
// 读取数据源
private DataSource dataSource;
....
}
我们可以发现,它的属性有
数据源
、
资源流
,因此,我们在
spring
中的配置的时候,就需要往相关的属性上赋值了 ;
spring
中配置
sqlSessionFactory
:
<!--配置 sqlSessionFactory-->
<!--
class :在 mybatis-spring 整合包里面
-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--设置读取 mybatis 配置文件的资源流-->
<property name="configLocation" value="xin/ijava/config/mybatis/sqlMapConfig.xml"/>
<!--设置数据源,引用下面配置的数据源对象-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--读取数据库的配置文件-->
<content:property-placeholder location="classpath:xin/ijava/config/mybatis/db.properties" />
<!--配置 DBCP 数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username"/>
<property name="password" value="${jdbc.password"/>
<property name="maxOpenPreparedStatements" value="10"/>
<property name="maxIdle" value="5"/>
</bean>
整合之后原始 dao 开发
-
开发接口
跟之前
mybatis
的原始开发一样,需要写接口 ;
-
配置映射关系文件
和之前单独使用
mybatis
开发是一样的 ;
-
开发实现类
跟之前
mybatis
的原始开发一样,写接口的实现类 ;
-
让实现类继承
SqlSessionDaoSupport
(
不同点
)
继承以后,我们不再需要写上
sqlSessionFactory
属性了,因为,在继承类中,有这个属性
获取
SqlSession
使用
this.getSqlSession()
并且,不再需要我们自己手动去关闭
sqlSession
;
/**
* @author An
*/
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{
@Override
public void insertUser(User user) throws Exception {
SqlSession sqlSession = this.getSqlSession() ;
sqlSession.insert("test.insertUser",user) ;
}
-
在
spring
中配置
userDao
对象
传入
sqlSessionFactory
对象 ;
<!--配置 UserDao-->
<bean id="userDao" class="xin.ijava.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
-
测试代码
public class UserDaoImplTest {
private ApplicationContext context ;
@Before
public void setUp() throws Exception {
context = new ClassPathXmlApplicationContext("xin/ijava/config/spring/application.xml");
}
@Test
public void findUserById() throws Exception {
UserDaoImpl userDao = (UserDaoImpl) context.getBean("userDao");
User user = userDao.findUserById(1) ;
System.out.println(user);
}
}
-
查看控制台输出
[service] 2018-09-12 17:26:22,538 - xin.ijava.dao.UserMapper.findUserById -8617 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Preparing: select * from User where id = ?
[service] 2018-09-12 17:26:22,720 - xin.ijava.dao.UserMapper.findUserById -8799 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Parameters: 1(Integer)
[service] 2018-09-12 17:26:22,806 - xin.ijava.dao.UserMapper.findUserById -8885 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - <== Total: 1
[service] 2018-09-12 17:26:22,815 - net.sf.ehcache.store.disk.Segment -8894 [main] DEBUG net.sf.ehcache.store.disk.Segment - put added 0 on heap
[service] 2018-09-12 17:26:22,824 - org.mybatis.spring.SqlSessionUtils -8903 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6dd93e5f]
[service] 2018-09-12 17:26:22,824 - org.springframework.jdbc.datasource.DataSourceUtils -8903 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
User : name = 张三,id = 1
只要看到这个输出,就说明
mybatis
和
spring
整合成功 !!
整合之后 Mapper 代理开发
-
配置
xxxMapper.xml
映射关系文件
跟之前
mybatis
的原始开发一样;
-
开发接口
跟之前
mybatis
的原始开发一样,需要写接口 ;
-
让
spring
创建代理对象
在
spring
的配置文件中,进行配置 ;
如果传入的
class
是整合包中的
MapperFactoryBean
类
这种方式,需要为每一个接口,都配置一次 ;
<!--配置映射文件代理对象-->
<!--
让 spring 创建代理对象。
-->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!--依然需要传入 sqlSessionFactory -->
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
<!--传入接口,告诉它为我们创建哪一个接口的代理对象-->
<property name="mapperInterface" value="xin.ijava.dao.UserCustomerMapper"/>
</bean>
如果传入的
class
是整合包中的
MapperScannerConfigurer
类
这种方式,会批量的扫描接口,我们只需要配置这一次 ;
注意,这里传
sqlSessionFactory
进去的时候,使用的是
sqlSessionFactoryBeanName
;
<!--扫描包下的所有接口,一次性生成诸多代理对象,并在 spring 中注册-->
<!--自动创建的代理对象的 id 为 类名字(首字母小写,必须小写)-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--配置包名 -->
<!--要是扫描多个包,中间用逗号隔开-->
<property name="basePackage" value="xin.ijava.dao"/>
<!--依然传入 sqlSessionFactory-->
<!--value 的值是之前配置的 SqlSessionFactory 的 id-->
<!--这里 name 不能写 sqlSessionFactory ,因为这里先执行;
假如写为sqlSessionFactory属性,那么上面配置的加载数据库配置文件的配置,将不会得到执行 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
如果使用了批量注册注册
mapper
,那么
mybatis
的配置文件中就 不再需要进行
mapper.xml
的扫描;
对了,这里有个坑,除了使用
sqlSessionFactoryBeanName
代替
sqlSessionFactory
;还需要去掉开头的
default-autowire="byName"
;
-
使用批量加载的方法的测试代码
public class UserCustomerMapperTest {
private ApplicationContext context ;
@Before
public void setUp() throws Exception {
context = new ClassPathXmlApplicationContext("xin/ijava/config/spring/application.xml");
}
@Test
public void findOrderUsers() throws Exception {
UserCustomerMapper userCustomerMapper = (UserCustomerMapper) context.getBean("userCustomerMapper");
List<UserCustomer> userCustomers = userCustomerMapper.findOrderUsers();
System.out.println(userCustomers);
}
}
-
测试结果
[service] 2018-09-12 20:25:02,662 - org.mybatis.spring.transaction.SpringManagedTransaction -8640 [main] DEBUG org.mybatis.spring.transaction.SpringManagedTransaction - JDBC Connection [1728792864, URL=jdbc:mysql:///mybatisDay01?charset=utf-8, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring
[service] 2018-09-12 20:25:02,684 - xin.ijava.dao.UserCustomerMapper.findOrderUsers -8662 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrderUsers - ==> Preparing: SELECT `order`.* ,`user`.`name` ,`user`.sex FROM `order`,`user` WHERE `user`.id = `order`.user_id
[service] 2018-09-12 20:25:02,818 - xin.ijava.dao.UserCustomerMapper.findOrderUsers -8796 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrderUsers - ==> Parameters:
[service] 2018-09-12 20:25:02,927 - xin.ijava.dao.UserCustomerMapper.findOrderUsers -8905 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrderUsers - <== Total: 4
[service] 2018-09-12 20:25:02,937 - org.mybatis.spring.SqlSessionUtils -8915 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1c3bf543]
[service] 2018-09-12 20:25:02,937 - org.springframework.jdbc.datasource.DataSourceUtils -8915 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
[User : name = 朱小明,id = 0, User : name = 张三,id = 0, User : name = 张小明,id = 0, User : name = 张三,id = 0]
只要控制台出现了我们打印的对象,就说明
mybatis 和 spring 整合成功 !!
总结
让
spring
管理
sqlSessionFactory
,使用
单例模式
创建该对象 ;
根据
sqlSessionFactory
创建
sqlsession
,这一步由
mybatis
和
spring
整合 以后,自动完成,不需要我们配置 ;
Mapper
接口的代理对象 ,由
spring
管理这些代理对象 ;
-
导包
导入
spring
、mybatis
的包导入
mybatis-spring
整合包 ;
-
搭建工程目录
需要注意的一点,就是在创建包的时候,为
mybatis
、spring
都创建各自的配置文件包,便于管理 ;
-
导入
spring
、mybatis
的配置文件其中注意,
mybatis
的配置文件中的environments
标签的内容在和spring
整合以后,就被废弃了,也就是不再起作用了;也就是
数据源
、事务
,最后都由spring
进行管理了 ;废弃的
environments
标签内容 :<!--当和 spring 整合以后,environments 配置将废除-->
<environments default="development">
<environment id="development">
<!--事务管理,暂时有mybatis管-->
<transactionManager type="JDBC"/>
<!--数据源 暂时也由 mybatis 管理,以后都由 spring 来管理-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
-
在
spring
中管理sqlSessionFactory
sqlSessionFactory
不是我们在mybatis
中使用的那个接口,而是在mybatis-spring
SqlSessionFactoryBean
;SqlSessionFactoryBean
类部分源码:public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
private static final Log LOGGER = LogFactory.getLog(SqlSessionFactoryBean.class);
// 读取mybatis配置文件使用的资源流
private Resource configLocation;
.....
// 读取数据源
private DataSource dataSource;
.... }
我们可以发现,它的属性有
数据源
、资源流
,因此,我们在spring
中的配置的时候,就需要往相关的属性上赋值了 ;spring
中配置sqlSessionFactory
:<!--配置 sqlSessionFactory-->
<!--
class :在 mybatis-spring 整合包里面
-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--设置读取 mybatis 配置文件的资源流-->
<property name="configLocation" value="xin/ijava/config/mybatis/sqlMapConfig.xml"/>
<!--设置数据源,引用下面配置的数据源对象-->
<property name="dataSource" ref="dataSource"/>
</bean> <!--读取数据库的配置文件-->
<content:property-placeholder location="classpath:xin/ijava/config/mybatis/db.properties" /> <!--配置 DBCP 数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username"/>
<property name="password" value="${jdbc.password"/>
<property name="maxOpenPreparedStatements" value="10"/>
<property name="maxIdle" value="5"/>
</bean>
整合之后原始 dao 开发
-
开发接口
跟之前
mybatis
的原始开发一样,需要写接口 ;
-
配置映射关系文件
和之前单独使用
mybatis
开发是一样的 ;
-
开发实现类
跟之前
mybatis
的原始开发一样,写接口的实现类 ;
-
让实现类继承
SqlSessionDaoSupport
(
不同点
)
继承以后,我们不再需要写上
sqlSessionFactory
属性了,因为,在继承类中,有这个属性
获取
SqlSession
使用
this.getSqlSession()
并且,不再需要我们自己手动去关闭
sqlSession
;
/**
* @author An
*/
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{
@Override
public void insertUser(User user) throws Exception {
SqlSession sqlSession = this.getSqlSession() ;
sqlSession.insert("test.insertUser",user) ;
}
-
在
spring
中配置
userDao
对象
传入
sqlSessionFactory
对象 ;
<!--配置 UserDao-->
<bean id="userDao" class="xin.ijava.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
-
测试代码
public class UserDaoImplTest {
private ApplicationContext context ;
@Before
public void setUp() throws Exception {
context = new ClassPathXmlApplicationContext("xin/ijava/config/spring/application.xml");
}
@Test
public void findUserById() throws Exception {
UserDaoImpl userDao = (UserDaoImpl) context.getBean("userDao");
User user = userDao.findUserById(1) ;
System.out.println(user);
}
}
-
查看控制台输出
[service] 2018-09-12 17:26:22,538 - xin.ijava.dao.UserMapper.findUserById -8617 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Preparing: select * from User where id = ?
[service] 2018-09-12 17:26:22,720 - xin.ijava.dao.UserMapper.findUserById -8799 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Parameters: 1(Integer)
[service] 2018-09-12 17:26:22,806 - xin.ijava.dao.UserMapper.findUserById -8885 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - <== Total: 1
[service] 2018-09-12 17:26:22,815 - net.sf.ehcache.store.disk.Segment -8894 [main] DEBUG net.sf.ehcache.store.disk.Segment - put added 0 on heap
[service] 2018-09-12 17:26:22,824 - org.mybatis.spring.SqlSessionUtils -8903 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6dd93e5f]
[service] 2018-09-12 17:26:22,824 - org.springframework.jdbc.datasource.DataSourceUtils -8903 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
User : name = 张三,id = 1
只要看到这个输出,就说明
mybatis
和
spring
整合成功 !!
整合之后 Mapper 代理开发
-
配置
xxxMapper.xml
映射关系文件
跟之前
mybatis
的原始开发一样;
-
开发接口
跟之前
mybatis
的原始开发一样,需要写接口 ;
-
让
spring
创建代理对象
在
spring
的配置文件中,进行配置 ;
如果传入的
class
是整合包中的
MapperFactoryBean
类
这种方式,需要为每一个接口,都配置一次 ;
<!--配置映射文件代理对象-->
<!--
让 spring 创建代理对象。
-->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!--依然需要传入 sqlSessionFactory -->
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
<!--传入接口,告诉它为我们创建哪一个接口的代理对象-->
<property name="mapperInterface" value="xin.ijava.dao.UserCustomerMapper"/>
</bean>
如果传入的
class
是整合包中的
MapperScannerConfigurer
类
这种方式,会批量的扫描接口,我们只需要配置这一次 ;
注意,这里传
sqlSessionFactory
进去的时候,使用的是
sqlSessionFactoryBeanName
;
<!--扫描包下的所有接口,一次性生成诸多代理对象,并在 spring 中注册-->
<!--自动创建的代理对象的 id 为 类名字(首字母小写,必须小写)-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--配置包名 -->
<!--要是扫描多个包,中间用逗号隔开-->
<property name="basePackage" value="xin.ijava.dao"/>
<!--依然传入 sqlSessionFactory-->
<!--value 的值是之前配置的 SqlSessionFactory 的 id-->
<!--这里 name 不能写 sqlSessionFactory ,因为这里先执行;
假如写为sqlSessionFactory属性,那么上面配置的加载数据库配置文件的配置,将不会得到执行 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
如果使用了批量注册注册
mapper
,那么
mybatis
的配置文件中就 不再需要进行
mapper.xml
的扫描;
对了,这里有个坑,除了使用
sqlSessionFactoryBeanName
代替
sqlSessionFactory
;还需要去掉开头的
default-autowire="byName"
;
-
使用批量加载的方法的测试代码
public class UserCustomerMapperTest {
private ApplicationContext context ;
@Before
public void setUp() throws Exception {
context = new ClassPathXmlApplicationContext("xin/ijava/config/spring/application.xml");
}
@Test
public void findOrderUsers() throws Exception {
UserCustomerMapper userCustomerMapper = (UserCustomerMapper) context.getBean("userCustomerMapper");
List<UserCustomer> userCustomers = userCustomerMapper.findOrderUsers();
System.out.println(userCustomers);
}
}
-
测试结果
[service] 2018-09-12 20:25:02,662 - org.mybatis.spring.transaction.SpringManagedTransaction -8640 [main] DEBUG org.mybatis.spring.transaction.SpringManagedTransaction - JDBC Connection [1728792864, URL=jdbc:mysql:///mybatisDay01?charset=utf-8, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring
[service] 2018-09-12 20:25:02,684 - xin.ijava.dao.UserCustomerMapper.findOrderUsers -8662 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrderUsers - ==> Preparing: SELECT `order`.* ,`user`.`name` ,`user`.sex FROM `order`,`user` WHERE `user`.id = `order`.user_id
[service] 2018-09-12 20:25:02,818 - xin.ijava.dao.UserCustomerMapper.findOrderUsers -8796 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrderUsers - ==> Parameters:
[service] 2018-09-12 20:25:02,927 - xin.ijava.dao.UserCustomerMapper.findOrderUsers -8905 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrderUsers - <== Total: 4
[service] 2018-09-12 20:25:02,937 - org.mybatis.spring.SqlSessionUtils -8915 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1c3bf543]
[service] 2018-09-12 20:25:02,937 - org.springframework.jdbc.datasource.DataSourceUtils -8915 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
[User : name = 朱小明,id = 0, User : name = 张三,id = 0, User : name = 张小明,id = 0, User : name = 张三,id = 0]
只要控制台出现了我们打印的对象,就说明
mybatis 和 spring 整合成功 !!
总结
开发接口
跟之前
mybatis
的原始开发一样,需要写接口 ;
配置映射关系文件
和之前单独使用
mybatis
开发是一样的 ;
开发实现类
跟之前
mybatis
的原始开发一样,写接口的实现类 ;
让实现类继承
SqlSessionDaoSupport
(
不同点
)
继承以后,我们不再需要写上
sqlSessionFactory
属性了,因为,在继承类中,有这个属性
获取
SqlSession
使用
this.getSqlSession()
并且,不再需要我们自己手动去关闭
sqlSession
;
/**
* @author An
*/
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{
@Override
public void insertUser(User user) throws Exception {
SqlSession sqlSession = this.getSqlSession() ;
sqlSession.insert("test.insertUser",user) ;
}
在
spring
中配置
userDao
对象
传入
sqlSessionFactory
对象 ;
<!--配置 UserDao-->
<bean id="userDao" class="xin.ijava.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
测试代码
public class UserDaoImplTest {
private ApplicationContext context ;
@Before
public void setUp() throws Exception {
context = new ClassPathXmlApplicationContext("xin/ijava/config/spring/application.xml");
}
@Test
public void findUserById() throws Exception {
UserDaoImpl userDao = (UserDaoImpl) context.getBean("userDao");
User user = userDao.findUserById(1) ;
System.out.println(user);
}
}
查看控制台输出
[service] 2018-09-12 17:26:22,538 - xin.ijava.dao.UserMapper.findUserById -8617 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Preparing: select * from User where id = ?
[service] 2018-09-12 17:26:22,720 - xin.ijava.dao.UserMapper.findUserById -8799 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - ==> Parameters: 1(Integer)
[service] 2018-09-12 17:26:22,806 - xin.ijava.dao.UserMapper.findUserById -8885 [main] DEBUG xin.ijava.dao.UserMapper.findUserById - <== Total: 1
[service] 2018-09-12 17:26:22,815 - net.sf.ehcache.store.disk.Segment -8894 [main] DEBUG net.sf.ehcache.store.disk.Segment - put added 0 on heap
[service] 2018-09-12 17:26:22,824 - org.mybatis.spring.SqlSessionUtils -8903 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6dd93e5f]
[service] 2018-09-12 17:26:22,824 - org.springframework.jdbc.datasource.DataSourceUtils -8903 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
User : name = 张三,id = 1
只要看到这个输出,就说明
mybatis
和
spring
整合成功 !!
-
配置
xxxMapper.xml
映射关系文件跟之前
mybatis
的原始开发一样;
-
开发接口
跟之前
mybatis
的原始开发一样,需要写接口 ;
-
让
spring
创建代理对象在
spring
的配置文件中,进行配置 ;如果传入的
class
是整合包中的MapperFactoryBean
类这种方式,需要为每一个接口,都配置一次 ;
<!--配置映射文件代理对象-->
<!--
让 spring 创建代理对象。
-->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!--依然需要传入 sqlSessionFactory -->
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
<!--传入接口,告诉它为我们创建哪一个接口的代理对象-->
<property name="mapperInterface" value="xin.ijava.dao.UserCustomerMapper"/>
</bean>
如果传入的
class
是整合包中的MapperScannerConfigurer
类这种方式,会批量的扫描接口,我们只需要配置这一次 ;
注意,这里传
sqlSessionFactory
进去的时候,使用的是sqlSessionFactoryBeanName
;<!--扫描包下的所有接口,一次性生成诸多代理对象,并在 spring 中注册-->
<!--自动创建的代理对象的 id 为 类名字(首字母小写,必须小写)-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--配置包名 -->
<!--要是扫描多个包,中间用逗号隔开-->
<property name="basePackage" value="xin.ijava.dao"/>
<!--依然传入 sqlSessionFactory-->
<!--value 的值是之前配置的 SqlSessionFactory 的 id-->
<!--这里 name 不能写 sqlSessionFactory ,因为这里先执行;
假如写为sqlSessionFactory属性,那么上面配置的加载数据库配置文件的配置,将不会得到执行 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>如果使用了批量注册注册
mapper
,那么mybatis
的配置文件中就 不再需要进行mapper.xml
的扫描;对了,这里有个坑,除了使用
sqlSessionFactoryBeanName
代替sqlSessionFactory
;还需要去掉开头的default-autowire="byName"
;
-
使用批量加载的方法的测试代码
public class UserCustomerMapperTest {
private ApplicationContext context ;
@Before
public void setUp() throws Exception {
context = new ClassPathXmlApplicationContext("xin/ijava/config/spring/application.xml");
} @Test
public void findOrderUsers() throws Exception { UserCustomerMapper userCustomerMapper = (UserCustomerMapper) context.getBean("userCustomerMapper");
List<UserCustomer> userCustomers = userCustomerMapper.findOrderUsers();
System.out.println(userCustomers);
}
}
-
测试结果
[service] 2018-09-12 20:25:02,662 - org.mybatis.spring.transaction.SpringManagedTransaction -8640 [main] DEBUG org.mybatis.spring.transaction.SpringManagedTransaction - JDBC Connection [1728792864, URL=jdbc:mysql:///mybatisDay01?charset=utf-8, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring
[service] 2018-09-12 20:25:02,684 - xin.ijava.dao.UserCustomerMapper.findOrderUsers -8662 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrderUsers - ==> Preparing: SELECT `order`.* ,`user`.`name` ,`user`.sex FROM `order`,`user` WHERE `user`.id = `order`.user_id
[service] 2018-09-12 20:25:02,818 - xin.ijava.dao.UserCustomerMapper.findOrderUsers -8796 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrderUsers - ==> Parameters:
[service] 2018-09-12 20:25:02,927 - xin.ijava.dao.UserCustomerMapper.findOrderUsers -8905 [main] DEBUG xin.ijava.dao.UserCustomerMapper.findOrderUsers - <== Total: 4
[service] 2018-09-12 20:25:02,937 - org.mybatis.spring.SqlSessionUtils -8915 [main] DEBUG org.mybatis.spring.SqlSessionUtils - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1c3bf543]
[service] 2018-09-12 20:25:02,937 - org.springframework.jdbc.datasource.DataSourceUtils -8915 [main] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
[User : name = 朱小明,id = 0, User : name = 张三,id = 0, User : name = 张小明,id = 0, User : name = 张三,id = 0]只要控制台出现了我们打印的对象,就说明
mybatis 和 spring 整合成功 !!
总结
我们发现,其实无论是
原始开发
,还是
mapper
代理,
接口
和
映射关系文件
,都少不了!