Spring对MyBatis的整合思路
作为Bean容器,Spring框架提供了IoC机制,可以接管所有的组件的创建工作并进行依赖管理,整合的主要工作就是把Mybatis框架使用中所涉及的核心组件配置到Spring容器中,交给Spring和创建和管理。
具体来说,业务逻辑对象依赖基于Mybatis技术实现Dao对象,核心是获取SqlSession实例,则需要依赖SqlSessionFactory而SqlSessionFactory是SqlSessionFactoryBuider依据Mybatis配置文件中的数据源、SQL映射文件等信息来构建的。
整合优势:
Spring对Mybatis 进行整合,在对组件实现解耦的同时还能使Mybatis框架的使用变得更加方便和简单。此外,通过Spring提供的声明式事务等服务,能进一步简化开发工作量,提高开发效率。
Spring整合MyBatis的准备工作
1. 在项目中加入Spring、MyBatis及整合相关的JAR文件
2. 建立开发目录结构,创建实体类
public class User implements java.io.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; // 用户角色id
private Integer createdBy; // 创建者
private Date creationDate; // 创建时间
private Integer modifyBy; // 更新者
private Date modifyDate; // 更新时间
private String userRoleName; // 用户角色名称
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserCode() {
return userCode;
}
public void setUserCode(String userCode) {
this.userCode = userCode;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getUserRole() {
return userRole;
}
public void setUserRole(Integer userRole) {
this.userRole = userRole;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Integer getModifyBy() {
return modifyBy;
}
public void setModifyBy(Integer modifyBy) {
this.modifyBy = modifyBy;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
public String getUserRoleName() {
return userRoleName;
}
public void setUserRoleName(String userRoleName) {
this.userRoleName = userRoleName;
}
}
3.创建数据访问接口
public interface UserMapper {
public List<User> getUserList(User user);
}
4. 配置SQL映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd" >
<mapper namespace="cn.smbms.dao.user.UserMapper">
<!-- 当数据库中的字段信息与对象的属性不一致时需要通过resultMap来映射 -->
<resultMap type="User" id="userList">
<result property="userRoleName" column="roleName" />
</resultMap>
<!-- 查询用户列表(参数:对象入参) -->
<select id="getUserList" resultMap="userList" parameterMap="User">
SELECT u.*, r.roleName FROM smbms_user u, smbms_role r
WHERE u.userName LIKE CONCAT('%',#{userName},'%')
AND u.userRole = #{userRole} AND u.userRole = r.id
</select>
</mapper>
5. 配置MyBatis配置文件
<?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>
<properties resource="database.properties" />
<typeAliases>
<package name="cn.smbms.pojo"/>
</typeAliases>
</configuration>
实现Spring对MyBatis的整合
1. 配置数据源
建立Spring配置文件applicationContext-mybatis.xml配置数据源的关键代码
<!-- 配置数据源 -->
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
<property name="url"><value><![CDATA[jdbc:mysql://127.0.0.1:3306/smbms?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8]]></value></property>
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
2. 配置SqlSessionFactoryBean
<!-- 配置SqlSessionFactoryBean -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource" />
<property name="configLocation" value="classpath:mybatis-config.xml" />
<property name="mapperLocations">
<list><value>classpath:dao/*.xml</value></list>
</property>
</bean>
3. 使用SqlSessionTemplate实现数据库的操作
定义到接口的实现类,实现UserMapper
private SqlSessionTemplate sqlSession;
@Override
public List<User> getUserList(User user) {
// TODO Auto-generated method stub
return sqlSession.selectList("cn.smbms.dao.user.UserMapper.getUserList", user);
}
public SqlSessionTemplate getSqlSession() {
return sqlSession;
}
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
Spring配置文件代码
<!-- 配置SqlSessionTemplate -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- 配置DAO组件并注入SqlSessionTemplate实例 -->
<bean id = "userMapper" class="cn.smbms.dao.user.UserMapperImpl">
<property name="sqlSession" ref="sqlSessionTemplate">
</bean>
注意
- 创建SqlSessionTemplate实例时,需要通过其构造方法注入SqlSessionFactory实例.这里引用的是前文配置过的id为sqlSessionFactory的Bean。
- SqlSession与中默认的SqlSession实现不同,SqlSessionTemplate是线程安全的,可以以单例模式配置并被多个DAO对象共用,而不必为每个DAO单独配置一个SqlSessionTemplate实例.
3. 编写业务逻辑代码并测试
业务接口代码
public interface UserService {
public List<User> findUserWithConditions(User user);
}
业务实现类代码
public class UserServiceImpl implements UserService{
private UserMapper userMapper; //声明UserMapper接口引用
public List<User> findUserWithConditions(User user) {
try {
return userMapper.getUserList(user); //调用DAO方法实现查询
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
public UserMapper getUserMapper() {
return userMapper;
}
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
}
Spring配置文件中的代码
<bean id = "userService" class="cn.smbms.service.user.UserServiceImpl">
<property name="userMapper" ref="userMapper">
</bean>
测试类
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) ctx.getBean("userService");
User userCondition = new User();
userCondition.setUserName("赵");
userCondition.setUserRole(3);
List<User> userList = new ArrayList<User>();
userList = userService.findUserWithConditions(userCondition);
for (User user : userList) {
logger.debug("testGetUserList userCode: " + user.getUserCode()
+ "and userName: " + user.getUserName()
+ "and userRole: " + user.getUserRole()
+ "and userRoleName: " + user.getUserRoleName()
+ "and address: " + user.getAddress() );
}
User user = new User();
boolean result=userService.addNewUser(user);
logger.debug("testAdd result:"+result);
}
注入映射器实现
mybatis映射器机制,我们只需要定义好借口,mybatis帮我创建实现类,并且来管理SqlSession对象的创建和关闭,减少我们不少工作。缺点能就是不太够灵活。mybatis映射器注入可以选择两种方式,一种依赖MapperFactoryBean,另外一种方式依赖MapperScannerConfigure。
1. MapperFactoryBean
注意
SQL映射文件中须遵循的命名原则:
- 映射的命名空间和映射器接口的名称相同
- 映射元素的id和映射器接口的方法相同
2. MapperScannerConfigure
注意
- basePackage属性中可以包含多个包名,多个包名之间使用逗号或分号隔开。
- MapperScanerConfigrer会为所有由它创建的映射器实现开启自动装配。也就是说,创建的所有映射器实现都会被自动注入SqlSessionFactory实例。因此在示例11中配置DAO组件时无须显式注入SqlSessionFactory实例。
- 若环境中出于不同目的配置了多个SqlSessionFactory实例,自动装配将无法进行,此时应显式指定所依赖的SqlSessionFactory实例.配置方式如下所示.
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean" />
<property name="basePackage" value="dao" />
</bean>
为业务层添加声明式事务
<tx:method>
- propagation:
REQUIRED:默认值,通常用作增删改
SUPPORTS: 通常用作查询