MyBatis框架与Spring框架整合

Spring对MyBatis的整合思路
作为Bean容器,Spring框架提供了IoC机制,可以接管所有组件的创建工作并进行依赖管理,因而整合的主要工作就是把MyBatis框架使用中所涉及的核心组件配置到Spring容器中,交给Spring来创建和管理。
业务逻辑对象依赖基于MyBatis技术实现的Dao对象,核心是获取SqlSession实例。把创建实例的工作交给Spring来处理。

整合的步骤:
1.在项目中加入Spring、MyBatis及整合相关的JAR文件

jar包

2.建立开发目录,创建实体类

package cn.smbms.pojo;

import java.util.Date;

/**
 * @author Bryce
 *
 */
public class User {
    /*字段*/
    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 createBy;   //创建者
    private Date creationDate;  //创建时间
    private Integer modifyBy;   //更新者
    private Date modifyDate;    //更新时间

    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 getCreateBy() {
        return createBy;
    }
    public void setCreateBy(Integer createBy) {
        this.createBy = createBy;
    }
    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;
    }


}

3.创建数据访问接口

package cn.smbms.dao.user;

import java.util.List;

import cn.smbms.pojo.User;

public interface UserMapper {
    /**
     * 查询用户列表
     */
    public List<User> getUserList(User user);


}

4.配置SQL映射文件(Mapper)

<?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.smbms.dao.user.UserMapper">
    <!-- 查询用户表记录数 -->
    <select id="count" resultType="int">
        select count(1) as count from smbms_user
    </select>
    <!-- 查询用户列表 -->
    <select id="getUserList" resultType="cn.smbms.pojo.User">
        select * from smbms_user
    </select>
</mapper>

5.配置MyBatis配置文件(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.pojo"/>
    </typeAliases>
</configuration>

6.创建Spring配置文件applicationContext-mybatis.xml
7.配置数据源
添加dbcp数据源所需的JAR文件
jar
在applicationContext-mybatis.xml文件中添加配置信息

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&amp;characterEncoding=utf-8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456">    </property>
</bean>

8.配置SqlSessionFactoryBean(applicationContext-mybatis.xml)

    <!-- 配置SqlSessionFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 引用数据源组件 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 引用MyBatis配置文件中的配置 -->
        <property name="configLocation" value="classpath:mybatis-config.xml" />
        <!-- 配置SQL映射文件信息 -->
        <property name="mapperLocations">
            <list>
                <value>classpath:cn/smbms/dao/**/*.xml</value>
            </list>
        </property>
    </bean>

9.使用SqlSessionTemplate实现数据库的操作(dao接口实现类)

package cn.smbms.dao.user;

import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;

import cn.smbms.pojo.User;

public class UserMapperImpl implements UserMapper {
    private SqlSessionTemplate sqlSession;

    @Override
    public List<User> getUserList(User user) {
        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

    <!-- 配置SqlSessionTemplate -->
    <bean id="sqlSessionTemplate"class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
        <!-- 配置DAO -->
    <bean id="userMapper" class="cn.smbms.dao.user.UserMapperImpl">
        <property name="sqlSession" ref="sqlSessionTemplate" />
    </bean>

10.编写业务逻辑代码并测试
业务接口的关键代码:

package cn.smbms.service.user;

import java.util.List;
import cn.smbms.pojo.User;

public interface UserService {
    public List<User> findUsersWithConditions(User user);
}

业务实现类的关键代码:

package cn.smbms.service.user;

import java.util.List;

import cn.smbms.dao.user.UserMapper;
import cn.smbms.pojo.User;

public class UserServiceImpl implements UserService {
    private UserMapper userMapper;

    @Override
    public List<User> findUsersWithConditions(User user) {
        try {
            return userMapper.getUserList(user);
        } catch (RuntimeException e) {
            e.printStackTrace();
            throw e;
        }
    }

    public UserMapper getUserMapper() {
        return userMapper;
    }

    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

}

Spring配置文件中的关键代码:

    <!-- 配置业务Bean -->
    <bean id="userService" class="cn.smbms.service.user.UserServiceImpl">
        <property name="userMapper" ref="userMapper" />
    </bean>

使用MapperFactoryBean注入映射器
1.配置实现Dao(applicationContext-mybatis.xml)

    <!-- 使用MapperFactoryBean注入映射器 -->
    <bean id="billMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="cn.smbms.dao.bill.BillMapper"/>
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

业务组件的定义和配置及测试代码与之前相同。无须手工编码定义Mapper接口的实现类,通过配置MapperFactoryBean即可自动生成,减少了Dao模块的编码工作量。

使用MapperScannerConfigurer注入映射器
为了简化配置工作量,MyBatis-Spring中提供了MapperScannerConfigurer,它可以扫描指定包中的接口并将它们直接注册为MapperFactoryBean。
配置文件内容:

    <!-- 使用MapperScannerConfigurer注入映射器 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.smbms.dao"/>
    </bean>

basePackage属性指定了扫描的基准包,MapperScannerConfigurer将递归扫描基准包(包括各层级子包)下所有接口。如果它们在SQL映射文件中定义过,则将它们动态注册为MapperFactoryBean,如此即可批量产生映射器实现类。

使用MapperScannerConfigurer自动完成映射器注册后,使用@Autowired或者@Resource注解实现对业务组件的依赖注入,以简化业务组件的配置。

package cn.smbms.service.user;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.smbms.dao.user.UserMapper;
import cn.smbms.pojo.User;

@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired//依赖注入
    private UserMapper userMapper;  //声明BillMapper接口引用
    @Override
    public List<User> getUserList() {
        // TODO Auto-generated method stub
        return userMapper.getUserList();
    }
    @Override
    public boolean updateUser(User user) {
        // TODO Auto-generated method stub
        return userMapper.updateUser(user)>0;
    }
    @Override
    public boolean deleteUser(int id) {
        // TODO Auto-generated method stub
        return userMapper.deleteUser(id)>0;
    }
    @Override
    public boolean updateUserPassword(int id) {
        // TODO Auto-generated method stub
        return userMapper.updateUserPassword(id)>0;
    }



}

Spring配置文件中的关键代码:

    <!-- 配置扫描注解定义的业务Bean -->
        <context:component-scan base-package="cn.smbms.service" />

为业务层添加声明式事务

配置声明式事务的步骤
1.导入tx和aop命名空间
2.定义事务管理器Bean,并为其注入数据源Bean

       <!-- 定义事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

3.通过<tx:advice>配置事务增强,绑定事务管理器并针对不同方法定义事务规则。

    <!-- 通过<tx:advice>标签为指定的事务管理器设置事务属性 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <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:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

</tx:advice> 标签内可以设置id属性和transaction-manager属性。其中transaction-manager属性引用一个事务管理器Bean。

<tx:attributes>子标签定制事务属性。事务属性通过<tx:method>
标签进行设置。
<tx:method>标签中的name属性是必需的,用于指定匹配的方法。这里需要对方法名进行约定,可以使用通配符(*)。其他属性可选
propagation:事务传播机制。
REQUIRED:默认值,表示如果存在一个事务,则支持当前事务;如果当前没有事务,则开启一个新的事务
REQUIRES_NEW:表示总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起,开启新事务执行该方法。
MANDATORY: 表示如果存在一个事务,则支持当前事务;如果当前没有一个活动的事务,则抛出异常。
NESTED:表示如果当前存在一个活动的事务,则创建一个事务作为当前事务的嵌套事务运行:如果没有当前事务,该取值与REQUIRED相同。
SUPPORTS:表示如果存在一个事务,则支持当前事务;如果当前没有事务,则按非事务方式执行。
NOT_SUPPORTED:表示总是以非事务方式执行。如果一个事务已经存在,则将这个存在的事务挂起,然后执行该方法。
NEVER:表示总是以非事务方式执行。如果当前存在一个活动事务,则抛出异常。
isolation:事务隔离等级。即当前事务和其他事务的隔离程度。
DEFAULT: 默认值,表示使用数据库默认的事务隔离级别。
READ_UNCOMMITTED:未提交读。
READ_COMMITTED:提交读。
REPEATABLE_READ:可重复读。
SERIALIZABLE:串行读。
timeout:事务超时时间。允许事务运行的最长时间,以秒为单位
read-only:事务是否为只读,默认值false
rollback-for:设定能触发回滚的异常类型。
no-rollback-for:设定不触发回滚的异常类型。
4.配置切面,将事务增强与方法切入点组合。

    <!-- 定义切面 -->
    <aop:config>
        <aop:pointcut id="serviceMethod"
            expression="execution(* cn.smbms.service..*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" />
    </aop:config>

使用注解实现声明式事务处理
首先需要在Spring配置文件中配置事务管理类,并添加对注解配置的事务的支持

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager" />

使用@Transactional注解来配置事务

package cn.smbms.service.bill;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import cn.smbms.dao.bill.BillMapper;
import cn.smbms.pojo.Bill;

@Transactional
@Service("billService")
public class BillServiceImpl implements BillService {
    private BillMapper billMapper;  //声明BillMapper接口引用

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<Bill> getBillList() {
        // TODO Auto-generated method stub
        try {
            return billMapper.getBillList();
        } catch (RuntimeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw e;
        }
    }

    public BillMapper getBillMapper() {
        return billMapper;
    }

    public void setBillMapper(BillMapper billMapper) {
        this.billMapper = billMapper;
    }

    @Override
    public List<Bill> getBillList(Bill bill) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public boolean updateBill(Bill bill) {
        // TODO Auto-generated method stub
        return billMapper.updateBill(bill)>0;
    }

    @Override
    public boolean deleteBill(int id) {
        // TODO Auto-generated method stub
        return billMapper.deleteBill(id)>0;
    }




}

@Transaction注解也可以设置事务属性的值,默认设置如下
事务传播设置是PROPAGATION_REQUIRED.
事务隔离级别是ISOLATION_DEFAULT.
事务是读/写。
事务超时默认是依赖于事务系统的,或者事务超时没有被支持。
任何RuntimeException将触发事务回滚,但是任何checked Exception将不触发事务回滚。
@Transactional注解的属性


属性

类型

说明

propagation

枚举型:Propagation

可选的传播性设置。使用举例:

@Transactional(

propagation=Propagation.REQUIRES_NEW)

isolation

枚举型:Isolation

可选的隔离性级别。使用举例:

@Transactional(

isolation=Isolation.READ_COMMITTED)

readOnly

布尔型

是否为只读型事务。使用举例:@Transactional(readOnly=true)

timeout

int型(以秒为单位)

事务超时。使用举例:Transactional(timeout=10)

rollbackFor

一组 Class 类的实例,必须是Throwable的子类

一组异常类,遇到时 必须 回滚。使用举例:@Transactional(

rollbackFor={SQLException.class}),多个异常用逗号隔开

rollbackForClassName

一组 Class 类的名字,必须是Throwable的子类

一组异常类名,遇到时 必须 回滚。使用举例:@Transactional(

rollbackForClassName={

"SQLException"}),多个异常用逗号隔开

noRollbackFor

一组 Class 类的实例,必须是Throwable的子类

一组异常类,遇到时 必须不 回滚

noRollbackForClassName

一组 Class 类的名字,必须是Throwable的子类

一组异常类名,遇到时 必须不 回滚

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值