(五)Spring-spring和mybatis的整合
(五)Spring-spring和mybatis的整合
一、整合要点
1.1 准备工作
spring和mybatis的官网整合地址为:
http://www.mybatis.cn/archives/769.html
需要导入依赖:
org.mybatis
mybatis-spring
2.0.3
1.2 数据源替换
spring配置文件的数据源替换mybatis配置文件的数据源
1 原mybatis-config.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
2 用spring.xml替换为:
1.3 sqlSessionFactory替换
1 原mybatis实现为工具类
原来mybatis框架需要代码用工具类实现获取SqlSessionFactory,主要是通过读取原来mybatis的配置文件,获取数据源信息,生成SqlSessionFactory对象
如下
package com.happy.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.sql.DriverManager;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//使用mybatis第一步:获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
//InputStream inputStream = MybatisUtils.class.getClassLoader().getResourceAsStream(resource);
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//使用uat环境数据库
//sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,"uat");
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
public static void release(SqlSession sqlSession){
}
}
2 用spring.xml替换为:
在 MyBatis-Spring 中,可使用 SqlSessionFactoryBean 来创建 SqlSessionFactory。 要配置这个工厂 Bean,只需要把下面代码放在 Spring 的 XML 配置文件中:
1.4 获取Mapper方式替换
1 原mybatis实现为用工具类获取MybatisUtils.getSqlSession()
之前为在service层,通过在方法类使用工具类分两步获取mapper:
- MybatisUtils.getSqlSession()获取SqlSession,实际工具类为通过SqlSessionFactory获取
- 然后通过getSqlSession获取mapper
package com.happy.service.user.impl;
import com.happy.mapper.user.UserMapper;
import com.happy.pojo.User;
import com.happy.service.user.UserService;
import com.happy.utils.MybatisUtils;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserServiceImpl implements UserService {
UserMapper userMapper;
@Override
public List getUserList() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
userMapper = sqlSession.getMapper(UserMapper.class);
List userList = userMapper.getUserList();
return userList;
}
@Override
public User getUserById(int id) {
SqlSession sqlSession = MybatisUtils.getSqlSession();
userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(id);
return user;
}
@Test
public void test(){
List userList = getUserList();
System.out.println(userList);
}
@Test
public void testGetUserById(){
User user = getUserById(3);
System.out.println(user);
}
}
2 用spring.xml配置mapper
3 测试使用
用spring.xml配置mapper后,这样获取和使用:
package com.happy.service.user.impl;
import com.happy.mapper.user.UserMapper;
import com.happy.pojo.User;
import com.happy.service.user.UserService;
import com.happy.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier("userMapper")
UserMapper userMapper;
@Override
public List getUserList() {
List userList = userMapper.getUserList();
return userList;
}
@Override
public User getUserById(int id) {
User user = userMapper.getUserById(id);
return user;
}
@Test
public void testGetUserList(){
ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
UserService userService = context.getBean("userServiceImpl", UserService.class);
List userList =userService.getUserList();
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void testGetUserById(){
ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
UserService userService = context.getBean("userServiceImpl", UserService.class);
User user = userService.getUserById(3);
System.out.println(user);
}
}
1.5 小结
一般,最终结合后的项目总结构如下:
1 一个总配置文件application-context.xml用来配置spring总的配置
- application-context.xml如下,负责开启注解,包扫描等
- 注意import其他spring.xml文件
<?xml version="1.0" encoding="UTF-8"?>
2 总配置下导入其他组件配置(如spring-mybatis.xml,spring-mvc.xml)和业务bean(如spring-user.xml)
- spring-mybatis.xml如下,负责spring集成mybatis的所有配置,主要包括数据源和sqlSessionFactory
- 数据源可以引用外部properties文件。
- 注册mapper,通过
MapperFactoryBean将接口加入到 Spring 中,需要注意的是:所指定的映射器类必须是一个接口,而不是具体的实现类。在这个示例中,通过注解来指定 SQL 语句,但是也可以使用 MyBatis 映射器的 XML 配置文件 - MapperFactoryBean
在这里注册mapper,实际为mapper接口的一个动态代理(已经注入了sqlSession等属性) MapperFactoryBean将会负责SqlSession的创建和关闭。
<?xml version="1.0" encoding="UTF-8"?>
3 mybatis-config.xml原生配置文件
- mybatis-config.xml,mybatis原生配置文件将数据源、sqlSessionFactory等去掉(已在spring中配置)
- 注意在spring中配置中配置sqlSessionFactory的时候引用mybatis配置文件
- mybatis原生配置文件,一般保留配置如下(也可以全部放到spring中配置):
- typeAliases
mappers,负责mybatis的beans.xml文件和mapper接口映射- settings配置
<?xml version="1.0" encoding="UTF-8" ?>
4 编写mapper接口和mapper.xml文件
UserMapper.java
package com.happy.mapper.user;
import com.happy.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
@Select("select * from user")
List getUserList();
User getUserById(@Param("id") int id);
}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
5 service层调用mapper接口
- 可以使用spring.xml注册service层的bean,也可以使用@Service注解等注入容器
- 注册service的bean时,注意属性注入依赖mapper
- 使用时,如controller直接从容器中获取service的bean即可以实现业务。
- 配置好之后,你就可以像 Spring 中普通的 bean 注入方法那样,将映射器注入到你的业务或服务对象中。
MapperFactoryBean将会负责SqlSession的创建和关闭。 如果使用了 Spring 的事务功能,那么当事务完成时,session 将会被提交或回滚。最终任何异常都会被转换成 Spring 的DataAccessException异常。
package com.happy.service.user.impl;
import com.happy.mapper.user.UserMapper;
import com.happy.pojo.User;
import com.happy.service.user.UserService;
import com.happy.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier("userMapper")
UserMapper userMapper;
@Override
public List getUserList() {
List userList = userMapper.getUserList();
return userList;
}
@Override
public User getUserById(int id) {
User user = userMapper.getUserById(id);
return user;
}
@Test
public void testGetUserList(){
ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
UserService userService = context.getBean("userServiceImpl", UserService.class);
List userList =userService.getUserList();
for (User user : userList) {
System.out.println(user);
}
}
@Test
public void testGetUserById(){
ApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
UserService userService = context.getBean("userServiceImpl", UserService.class);
User user = userService.getUserById(3);
System.out.println(user);
}
}
二、整合方式二-使用 SqlSession
在 MyBatis 中,你可以使用 SqlSessionFactory 来创建 SqlSession。 一旦你获得一个 session 之后,你可以使用它来执行映射了的语句,提交或回滚连接,最后,当不再需要它的时候,你可以关闭 session。 使用 MyBatis-Spring 之后,你不再需要直接使用 SqlSessionFactory 了,因为你的 bean 可以被注入一个线程安全的 SqlSession,它能基于 Spring 的事务配置来自动提交、回滚、关闭 session。第二种方式又包括以下两种方式:
2.1 使用SqlSessionTemplate
SqlSessionTemplate 是 MyBatis-Spring 的核心。作为 SqlSession 的一个实现,这意味着可以使用它无缝代替你代码中已经在使用的 SqlSession。 SqlSessionTemplate 是线程安全的,可以被多个 DAO 或映射器所共享使用。
当调用 SQL 方法时(包括由 getMapper() 方法返回的映射器中的方法),SqlSessionTemplate 将会保证使用的 SqlSession 与当前 Spring 的事务相关。 此外,它管理 session 的生命周期,包含必要的关闭、提交或回滚操作。另外,它也负责将 MyBatis 的异常翻译成 Spring 中的 DataAccessExceptions。
由于模板可以参与到 Spring 的事务管理中,并且由于其是线程安全的,可以供多个映射器类使用,你应该总是用 SqlSessionTemplate 来替换 MyBatis 默认的 DefaultSqlSession 实现。在同一应用程序中的不同类之间混杂使用可能会引起数据一致性的问题。
可以使用 SqlSessionFactory 作为构造方法的参数来创建 SqlSessionTemplate 对象。
2.2 SqlSessionDaoSupport
SqlSessionDaoSupport 是一个抽象的支持类,用来为你提供 SqlSession。调用 getSqlSession() 方法你会得到一个 SqlSessionTemplate,之后可以用于执行 SQL 方法,就像下面这样:
2.3 小结
-
详细方法见官网:
http://mybatis.org/spring/zh/sqlsession.html#
-
注入映射器(参照方式一),与其在数据访问对象(DAO)中手工编写使用
SqlSessionDaoSupport或SqlSessionTemplate的代码,还不如让 Mybatis-Spring 为你创建一个线程安全的映射器,这样你就可以直接注入到其它的 bean 中了,如下面使用构造器注入,也可以使用属性注入。