Spring与MyBatis的整合
1.分析整合思路
作为Bean容器,Spring框架提供了IoC机制,可以接管所有组件的创建工作并进行依赖管理,因而整合的主要工作就是把MyBatis框架使用中所涉及的核心组件配置到Spring容器中,交给Spring来创建和管理。
2.整合前的准备工作
- 添加jar包
- 创建开发目录结构
- 创建数据访问接口
- 配置SQL映射文件
- 配置MyBatis配置文件
相关jar包:
创建开发目录结构
在cn.kgc.entity包下创建实体类
package cn.kgc.entity;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private Integer id; //id
private String userCode; //用户编码
private String userName; //用户名称
private String userPassword; //用户密码
private Integer gender; //性别
private Date birthday; //出生日期
private String phone; //电话
private String address; //地址
private Integer userRole; //用户角色
private Integer createdBy; //创建者
private Date creationDate; //创建时间
private Integer modifyBy; //更新者
private Date modifyDate; //更新时间
// 省略setter和getter方法
}
创建数据访问接口
在cn.kgc.dao下创建实体类对应的DAO接口UserMapper
package cn.kgc.dao;
public interface UserMapper {
public Integer count();
}
配置SQL映射文件
在resource文件下创建mapper目录,在mapper目录中创建usermapper.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.kgc.dao.UserMapper">
<!-- 查询用户总数 -->
<select id="count" resultType="integer">
select count(1) from smbms_user
</select>
</mapper>
配置MyBatis配置文件
在resources文件下创建mybatis-config.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="cn.smbms.entity"/>
</typeAliases>
</configuration>
3.实现Spring对MyBatis的整合
关键步骤如下:
- 配置DataSource数据源
- 配置SqlSessionFactoryBean
- 使用SqlSessionTemplate进行持久化操作
- 编写测试类测试运行结果
在resources文件下创建applicationcontext.xml文件编写相关配置
文件中代码如下:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>
<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="cn.kgc.entity"/>
<!--<property name="configLocation" value="mybatis-config.xml"/>-->
<property name="mapperLocations">
<list>
<value>classpath:mapper/usermapper.xml</value>
<value>classpath:billmapper.xml</value>
</list>
</property>
</bean>
<!-- 配置SqlSessionTemplate -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
</bean>
<bean id="userMapper" class="cn.kgc.dao.UserMapperImpl">
<property name="sqlSessionTemplate" ref="sqlSessionTemplate"/>
</bean>
</beans>
以上代码完成了数据源DataSource、SqlSessionFactoryBean、SqlSessionTemplate的配置。在配置SqlSessionTemplate要创建UserMapper的实现类
public class UserMapperImpl implements UserMapper {
private SqlSessionTemplate sqlSessionTemplate;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSessionTemplate = sqlSession;
}
@Override
public Integer count() {
return sqlSessionTemplate.getMapper(UserMapper.class).count();
}
}
该UserMapper的实现类可以通过继承SqlSessionDaoSupport方法简化,简化后代码如下:
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
@Override
public Integer count() {
return this.getSqlSession().getMapper(UserMapper.class).count();
}
}
完成DAO组件的装配后,在cn.kgc.service包下业务组件并通过Spring装配
package cn.kgc.service;
public interface UserService {
public Integer findCountUser();
}
业务实现类:
package cn.kgc.service.impl;
import cn.kgc.dao.UserMapper;
import cn.kgc.entity.User;
import cn.kgc.service.UserService;
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
// 查询用户总数
@Override
public Integer findCountUser() {
return userMapper.count();
}
}
该业务实现类是通过注解设值注入,所以需要在applicationcontext.xml配置文件中
添加如下代码:
<!-- 加入service注解-->
<context:component-scan base-package="cn.kgc.service"/>
注意若添加注解需在applicationcontext.xml配置文件前面加上以下代码
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
编写测试代码
package cn.kgc.test;
import cn.kgc.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserTest {
// 查询用户总数
@Test
public void testCountUser() {
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationcontext.xml");
UserService userService = (UserService)context.getBean("userService");
System.out.println("用户总数为: " + userService.findCountUser());
}
}
4.掌握注入映射器的两种方式
- 配置MapperFactoryBean生成映射器实现并注入到业务组件。
- 配置MapperScannerConfigurer生成映射器实现并注入到业务组件。
在之前的代码基础上,删除UserMapper的实现类,修改后的applicationcontext.xml文件如下:
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>
<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="cn.kgc.entity"/>
<!--<property name="configLocation" value="mybatis-config.xml"/>-->
<property name="mapperLocations">
<list>
<value>classpath:mapper/usermapper.xml</value>
<value>classpath:billmapper.xml</value>
</list>
</property>
</bean>
<!-- 注入映射器的两种方式 1: -->
<!-- 配置MapperFactoryBean 注册映射器(使用后不需配置SqlSessionTemplate) -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="cn.kgc.dao.UserMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<!-- 注入映射器的两种方式 2: -->
<!-- 在Spring配置文件中使用MapperFactoryBean对映射器进行配置-->
<!--<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.kgc.dao"/>
</bean>-->
</beans>
5.添加声明式事务
- 使用XML配置方法配置声明式事务
- 使用注解添加声明式
使用XML配置方法配置声明式事务
配置步骤:
- 导入tx和aop命名空间
- 定义事务管理器Bean,并为其注入数据源Bean
- 通过tx:advice配置事务增强,绑定事务管理器分并针对不同方法定义事务规则
- 配置切面,将事务增强与方法切入点组合。
具体实现步骤如下:
首先在UserMapper中添加如下代码
public Integer addUser(User user);
在usermapper.xml文件中添加如下代码:
<!-- 添加用户 -->
<insert id="addUser" parameterType="user">
insert into smbms_user (userCode,userName) values (#{userCode},#{userName})
</insert>
在业务接口UserService中添加如下代码:
public boolean addUser(User user);
在业务接口实现类UserServiceImpl中添加如下代码:
// 增加用户
@Override
public boolean addUser(User user) {
boolean result = false;
if (userMapper.addUser(user) == 1) {
// throw new RuntimeException();
result = true;
}
return result;
}
在applicationcontext.xml文件中首先需要导入tx和aop这两个命名空间
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="" 中添加:
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
在applicationcontext.xml文件中添加如下代码:
<!-- !!!!!!!!!!!!!!!!!!!!!!!! 事务控制模块 !!!!!!!!!!!!!!!!!-->
<!-- 1. 使用 配置 方式添加事务控制-->
<!-- 数据源进行事务控制(添加bean组件) -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 事务策略 tx:advice-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="find*" propagation="SUPPORTS"/>
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 定义切面 -->
<aop:config>
<aop:pointcut id="serviceMethod" expression="execution(* cn.kgc.service.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
</aop:config>
在测试类中添加如下代码:
// 测试增加用户
@Test
public void testAddUser() {
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationcontext.xml");
UserService userService = (UserService)context.getBean("userService");
User users = new User();
users.setUserName("马");
users.setUserCode("sdfdf");
System.out.println(userService.addUser(users));
}
在业务接口实现类UserServiceImpl中userMapper.addUser(user) 的if语句中抛出一个运行时异常,运行测试代码后,若在数据库中没有看到添加的新用户,则证明该事务处理代码没有问题。
使用注解方式添加声明式事务
在applicationcontext.xml文件中将之前的声明事务的方式改为如下:
!-- !!!!!!!!!!!!!!!!!!!!!!!! 事务控制模块 !!!!!!!!!!!!!!!!!-->
<!-- 1. 使用 配置 方式添加事务控制-->
<!-- 数据源进行事务控制(添加bean组件) -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 2. 使用 注解 的方式添加事务控制-->
<tx:annotation-driven transaction-manager="txManager"/>
在业务实现类中代码改为如下:
package cn.kgc.service.impl;
import cn.kgc.dao.UserMapper;
import cn.kgc.entity.User;
import cn.kgc.service.UserService;
@Transactional
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
// 查询用户总数
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public Integer findCountUser() {
return userMapper.count();
}
// 增加用户
@Override
@Transactional(propagation = Propagation.REQUIRED)
public boolean addUser(User user) {
boolean result = false;
if (userMapper.addUser(user) == 1) {
// throw new RuntimeException();
result = true;
}
return result;
}
}
在业务实现类中添加@Transactional注解,测试其是否正确的方法同上。