Spring使用篇(十)—— Spring与MyBatis整合

1 导入整合开发包

  为了整合Spring框架与MyBatis框架,首先需要导入jar包:mybatis-spring-1.3.0.

2 搭建案例演示环境

  第一步,在Spring_Demo项目中创建名为“SpringMyBatis”的普通Java模块。

  第二步,在该模块中创建名为lib的文件夹用于存放该模块所需的全部jar包, 具体如下图所示:
Spring使用篇(十)—— Spring与MyBatis整合
Spring使用篇(十)—— Spring与MyBatis整合
Spring使用篇(十)—— Spring与MyBatis整合
Spring使用篇(十)—— Spring与MyBatis整合
  第三步,创建如下图所示的包结构, 其中:annotation包中存放Java配置类;mapper包中存放数据库操作接口;pojo包中存放POJO类;sql包中存放MyBatis框架所需的数据库XML文件;test包中存放测试类;database-config.properties属性文件用于存储数据库四要素属性值;log4j.properties为日志配置属性文件;spring-config.xml为Spring框架配置文件;SqlMapConfig.xml为MyBatis框架的核心配置文件。
Spring使用篇(十)—— Spring与MyBatis整合
  第四步,在MySQL数据库中创建名为“chapter12”的数据库, 数据库字符集为UTF-8。在该数据库中创建名为“t_role”的数据表,具体表结构如下所示:
Spring使用篇(十)—— Spring与MyBatis整合
  第五步,在pojo包下创建名为“Role”的POJO类。 具体代码如下所示:

package com.ccff.spring.pojo;

import org.springframework.stereotype.Component;

@Component
public class Role {
    private Long id;
    private String roleName;
    private String roleNote;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getRoleNote() {
        return roleNote;
    }

    public void setRoleNote(String roleNote) {
        this.roleNote = roleNote;
    }

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", roleName='" + roleName + '\'' +
                ", roleNote='" + roleNote + '\'' +
                '}';
    }
}

  第六步,在mapper包中创建名为“RoleMapper”的接口。 该接口提供了对表t_role的一系列操作,具体代码如下所示:

package com.ccff.spring.mapper;

import com.ccff.spring.pojo.Role;
import org.springframework.stereotype.Repository;

public interface RoleMapper {
    public int insertRole(Role role);
    public Role getRoleById(Long id);
    public int updateRole(Role role);
    public int deleteRole(Long id);
}

  第七步,在sql包中创建名为“RoleMapper.xml”的SQL映射文件。 在该映射文件中给出对数据库的具体操作,代码如下所示:

<?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="com.ccff.spring.mapper.RoleMapper">

	<insert id="insertRole" parameterType="Role" useGeneratedKeys="true" keyProperty="id">
		insert into t_role(roleName, roleNote) values (#{roleName}, #{roleNote})
		<selectKey resultType="int" keyProperty="id" order="AFTER">
			select @@identity
		</selectKey>
	</insert>

	<delete id="deleteRole" parameterType="long">
		delete from t_role where id=#{id}
	</delete>

	<select id="getRoleById" parameterType="long" resultType="Role">
		select id, roleName, roleNote from t_role where id = #{id}
	</select>

	<update id="updateRole" parameterType="Role">
		update t_role
		set roleName = #{roleName},
		roleName = #{roleName}
		where id = #{id}
	</update>
</mapper>

  第八步,在annotation包中创建名为“ApplicationConfig”的Spring Java配置类。 在该配置类中,添加扫描的类所在的包以及加载XML配置资源文件。具体代码如下所示:

package com.ccff.spring.annotation;

import com.ccff.spring.pojo.Role;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@Configuration
@ComponentScan(basePackageClasses = {Role.class})
@ImportResource({"classpath:spring-config.xml"})
public class ApplicationConfig {
}

3 配置相关配置文件

  在单独使用MyBatis框架时,在配置MyBatis的全局配置文件SqlMapConfig.xml时,必须配置environments数据库环境配置,在该配置中需要配置数据库事务管理以及数据库连接池。但在Spring与MyBatis进行整合时,对数据源的配置将由MyBatis的全局配置中转移到Spring中配置。

3.1 配置数据源

  第一步,在spring-config.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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!--加载属性文件-->
    <context:property-placeholder location="database-config.properties" ignore-resource-not-found="true" />

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.database.driver}" />
        <property name="url" value="${jdbc.database.url}" />
        <property name="username" value="${jdbc.database.username}" />
        <property name="password" value="${jdbc.database.password}" />
        <!--连接池的最大数据库连接数 -->
        <property name="maxActive" value="255" />
        <!--最大等待连接中的数量 -->
        <property name="maxIdle" value="5" />
        <!--最大等待毫秒数 -->
        <property name="maxWait" value="10000" />
    </bean>
</beans>

  从上面的配置中可以看出,在配置数据源的过程中,对连接数据库四要素时使用了属性文件的配置形式,因此,需要在database-config.properties中配置连接数据库四要素具体如下:

jdbc.database.driver=com.mysql.jdbc.Driver
jdbc.database.url=jdbc:mysql://localhost:3306/chapter12
jdbc.database.username=root
jdbc.database.password=root

3.2 配置SqlSessionFactoryBean

  第二步,在Spring配置文件中配置SqlSessionFactoryBean。 由MyBatis框架可知,SqlSessionFactory是产生SqlSession的基础,因此配置SqlSessionFactory十分关键。因此,在MyBatis-Spring项目中提供了SqlSessionFactoryBean去支持SqlSessionFactory的配置。配置SqlSessionFactoryBean,还需要配置数据源并引入MyBatis全局配置文件。具体配置如下所示:

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!--加载属性文件-->
    <context:property-placeholder location="database-config.properties" ignore-resource-not-found="true" />

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.database.driver}" />
        <property name="url" value="${jdbc.database.url}" />
        <property name="username" value="${jdbc.database.username}" />
        <property name="password" value="${jdbc.database.password}" />
        <!--连接池的最大数据库连接数 -->
        <property name="maxActive" value="255" />
        <!--最大等待连接中的数量 -->
        <property name="maxIdle" value="5" />
        <!--最大等待毫秒数 -->
        <property name="maxWait" value="10000" />
    </bean>

	<!-- 配置SqlSessionFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:SqlMapConfig.xml" />
    </bean>

</beans>

3.3 配置SqlMapConfig.xml

  第三步,配置MyBatis框架全局配置文件SqlMapConfig.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>

    <settings>
        <!-- 这个配置使全局的映射器启用或禁用缓存 -->
        <setting name="cacheEnabled" value="true" />
        <!-- 允许 JDBC 支持生成的键。需要适合[修改为:适当]的驱动。如果设置为true,则这个设置强制生成的键被使用,尽管一些驱动拒绝兼容但仍然有效(比如 Derby) -->
        <setting name="useGeneratedKeys" value="true" />
        <!-- 配置默认的执行器。SIMPLE 执行器没有什么特别之处。REUSE 执行器重用预处理语句。BATCH 执行器重用语句和批量更新  -->
        <setting name="defaultExecutorType" value="REUSE" />
        <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 设置超时时间,它决定驱动等待一个数据库响应的时间  -->
        <setting name="defaultStatementTimeout" value="25000"/> 
    </settings>
    
    <!-- 别名配置 -->
    <typeAliases>
        <typeAlias alias="Role" type="com.ccff.spring.pojo.Role" />
    </typeAliases>
 
    <!-- 指定映射器路径 -->
    <mappers>
        <mapper resource="com/ccff/spring/sql/RoleMapper.xml" />
    </mappers>
    
</configuration>

3.4 配置MapperFactoryBean

  第四步,在Spring配置文件中配置MapperFactoryBean。 根据MyBatis框架的使用方法可知,在MyBatis中,对数据库的一系列操作都放在对应的Mapper XML文件中,而在Java中则仅以接口的形式给出,通过MyBatis的自动映射机制即可在不需要接口实现类的情况下完成映射。

  正式因为如此,MyBatis的运行是通过它内部创建的动态代理对象运行的,所以Spring也没有办法为其生成实现类并对其进行管理。为解决这个问题,MyBatis-Spring项目提供了一个MapperFactoryBean类作为中介,我们可以通过在Spring的配置文件中配置MapperFactoryBean来实现我们想要的Mapper。具体配置如下:

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!--加载属性文件-->
    <context:property-placeholder location="database-config.properties" ignore-resource-not-found="true" />

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.database.driver}" />
        <property name="url" value="${jdbc.database.url}" />
        <property name="username" value="${jdbc.database.username}" />
        <property name="password" value="${jdbc.database.password}" />
        <!--连接池的最大数据库连接数 -->
        <property name="maxActive" value="255" />
        <!--最大等待连接中的数量 -->
        <property name="maxIdle" value="5" />
        <!--最大等待毫秒数 -->
        <property name="maxWait" value="10000" />
    </bean>

    <!-- 配置SqlSessionFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:SqlMapConfig.xml" />
    </bean>

	<!-- 配置MapperFactoryBean-->
     <bean id="roleMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.ccff.spring.mapper.RoleMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

</beans>

  MapperFactoryBean存在3个属性可以配置,分别是mapperInterface、sqlSessionFactory和sqlSessionTemplate。其中:
  mapperInterface是映射器的接口;
  如果同时配置sqlSessionTemplate和sqlSessionFactory,那么它就会启用sqlSessionTemplate,而sqlSessionFactory作废。

  至此,对Spring与MyBatis的整合其实已经完成,已经可以开发测试了。但是,当项目比较大时,这种对每个Mapper文件都进行一个配置的方式显然是很不可取的,因此我们可以通过配置MapperScannerConfigurer,通过它可以用扫描的形式去生成对应的Mapper文件。

3.5 配置MapperScannerConfigurer

  第五步,在Spring配置文件中配置MapperScannerConfigurer。 具体配置如下:

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!--加载属性文件-->
    <context:property-placeholder location="database-config.properties" ignore-resource-not-found="true" />

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.database.driver}" />
        <property name="url" value="${jdbc.database.url}" />
        <property name="username" value="${jdbc.database.username}" />
        <property name="password" value="${jdbc.database.password}" />
        <!--连接池的最大数据库连接数 -->
        <property name="maxActive" value="255" />
        <!--最大等待连接中的数量 -->
        <property name="maxIdle" value="5" />
        <!--最大等待毫秒数 -->
        <property name="maxWait" value="10000" />
    </bean>

    <!-- 配置SqlSessionFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:SqlMapConfig.xml" />
    </bean>

    <!-- 配置MapperFactoryBean-->
     <!--<bean id="roleMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.ccff.spring.mapper.RoleMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>-->

	<!-- 配置MapperScannerConfigurer-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.ccff.spring.mapper" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        <!-- 指定标注才扫描成为Mapper -->
        <property name="annotationClass" value="org.springframework.stereotype.Repository" />
    </bean>
</beans>

  通过上面的配置可知,MapperScannerConfigurer主要配置项如下:
  basePackage: 指定让Spring自动扫描什么包,它会逐层深入扫描,如果遇到多个包可以使用半角逗号分隔;
  sqlSessionFactoryBeanName: 指定在Spring中定义SqlSessionFactory的Bean的名称。如果sqlSessionTemplateBeanName被定义,那么它将失去作用;
  annotationClass: 表示如果类被这个注解标识时候,才进行扫描。对于开发而言,建议使用这个方式进行注册对应的Mapper。在Spring中往往使用注解 @Repository 表示数据访问层(DAO)。本篇文章中使用此方法,而不配置markerInterface;
  markerInterface: 指定实现了什么接口就人为它是Mapper,需要提供一个公共接口去标记。

3.6 添加@Repository注解

  第六步,为Mapper接口添加@Repository注解。 为mapper包中的RoleMapper添加注解@Repository,表示这个一个DAO层,同时为了告诉Spring在扫描Mapper接口文件时扫描该包。这样就可以扫描出对应的Mapper到Spring IoC容器中。具体代码如下所示:

package com.ccff.spring.mapper;

import com.ccff.spring.pojo.Role;
import org.springframework.stereotype.Repository;

@Repository
public interface RoleMapper {
    public int insertRole(Role role);
    public Role getRoleById(Long id);
    public int updateRole(Role role);
    public int deleteRole(Long id);
}

4 测试Spring+MyBatis

  在test包中创建名为“RoleTest”的测试类用于测试Spring框架整合MyBatis框架后对Role以及数据表t_role进行操作。具体代码如下所示:

package com.ccff.spring.test;

import com.ccff.spring.annotation.ApplicationConfig;
import com.ccff.spring.mapper.RoleMapper;
import com.ccff.spring.pojo.Role;
import org.junit.Before;
import org.junit.Test;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class RoleTest {
    Role role = null;
    RoleMapper roleMapper = null;
    ApplicationContext context = null;

    @Before
    public void getContext(){
        context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
        role = context.getBean(Role.class);
        roleMapper = context.getBean(RoleMapper.class);
    }
    
    @Test
    public void test(){
        /**
         * 测试插入
         */
        role.setRoleName("role-name-1");
        role.setRoleNote("role-note-1");
        roleMapper.insertRole(role);

        /**
         * 测试查询
         */
        role = roleMapper.getRoleById(role.getId());
        System.out.println(role);

        /**
         * 测试修改
         */
        role.setRoleName("update-role-name-1");
        role.setRoleNote("update-role-note-1");
        roleMapper.updateRole(role);

        /**
         * 测试删除
         */
        roleMapper.deleteRole(role.getId());
    }

}

  运行插入测试代码后得到如下日志信息:
Spring使用篇(十)—— Spring与MyBatis整合
  查看t_role表得到如下数据(由于之前有测试数据的存在,因此id不是从1开始的):
Spring使用篇(十)—— Spring与MyBatis整合
  运行查询测试代码后得到如下日志信息:
Spring使用篇(十)—— Spring与MyBatis整合
  运行修改代码得到如下日志信息:
Spring使用篇(十)—— Spring与MyBatis整合
  查看t_role表得到如下结果:
Spring使用篇(十)—— Spring与MyBatis整合
  运行删除代码后,查看得到如下日志信息:
Spring使用篇(十)—— Spring与MyBatis整合

5、配置SqlSessionTemplate组件

  严格来讲,SqlSessionTemplate并不是一个必须配置的组件,但是它也存在一定的价值。首先,它是线程安全的类,也就是确保每个线程使用的SqlSession是唯一且不互相冲突。其次,它提供了一系列的功能,比如增、删、查、改等常用功能,不过在此之前需要先配置它。即在Spring的配置文件中对SqlSessionTemplate组件配置如下:

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <!--加载属性文件-->
    <context:property-placeholder location="database-config.properties" ignore-resource-not-found="true" />

    <!-- 数据库连接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.database.driver}" />
        <property name="url" value="${jdbc.database.url}" />
        <property name="username" value="${jdbc.database.username}" />
        <property name="password" value="${jdbc.database.password}" />
        <!--连接池的最大数据库连接数 -->
        <property name="maxActive" value="255" />
        <!--最大等待连接中的数量 -->
        <property name="maxIdle" value="5" />
        <!--最大等待毫秒数 -->
        <property name="maxWait" value="10000" />
    </bean>

    <!-- 配置SqlSessionFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:SqlMapConfig.xml" />
    </bean>

    <!-- 配置SqlSessionTemplate-->
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg ref="sqlSessionFactory" />
        <constructor-arg value="BATCH"/>
    </bean>

	<!-- 配置MapperScannerConfigurer-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.ccff.spring.mapper" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        <!-- 使用sqlSessionTemplateBeanName将覆盖sqlSessionFactoryBeanName的配置 -->
        <!-- <property name="sqlSessionTemplateBeanName" value="sqlSessionFactory"/> -->
        <!-- 指定标注才扫描成为Mapper -->
        <property name="annotationClass" value="org.springframework.stereotype.Repository" />
    </bean>
</beans>

  SqlSessionTemplate要通过带有参数的构造方法去创建对象,常用的参数是SqlSessionFactory和MyBatis执行器(Executor)类型,取值范围是SIMPLE、REUSE、BATCH。

  配置好SqlSessionTemplate后,在test包中的RoleTest测试类中添加名为“testSqlSessionTemplate”的测试方法,具体代码如下:

package com.ccff.spring.test;

import com.ccff.spring.annotation.ApplicationConfig;
import com.ccff.spring.mapper.RoleMapper;
import com.ccff.spring.pojo.Role;
import org.junit.Before;
import org.junit.Test;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class RoleTest {
    Role role = null;
    RoleMapper roleMapper = null;
    ApplicationContext context = null;

    @Before
    public void getContext(){
        context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
        role = context.getBean(Role.class);
        roleMapper = context.getBean(RoleMapper.class);
    }

    @Test
    public void testSqlSessionTemplate(){
        SqlSessionTemplate sqlSessionTemplate = context.getBean(SqlSessionTemplate.class);
        //添加用户
        Role role = context.getBean(Role.class);
        role.setRoleName("role-name-sqlSessionTemplate");
        role.setRoleNote("role-note-sqlSessionTemplate");
        sqlSessionTemplate.insert("com.ccff.spring.mapper.RoleMapper.insertRole",role);

        //查询用户
        Long id = role.getId();
        role = sqlSessionTemplate.selectOne("com.ccff.spring.mapper.RoleMapper.getRoleById",id);
        System.out.println(role);

        //更新用户
        role.setRoleName("update-role-name-sqlSessionTemplate");
        sqlSessionTemplate.update("com.ccff.spring.mapper.RoleMapper.updateRole",role);

        //删除用户
        sqlSessionTemplate.delete("com.ccff.spring.mapper.RoleMapper.deleteRole",id);
    }

    @Test
    public void test(){
        /**
         * 测试插入
         */
        role.setRoleName("role-name-1");
        role.setRoleNote("role-note-1");
        roleMapper.insertRole(role);

        /**
         * 测试查询
         */
        role = roleMapper.getRoleById(role.getId());
        System.out.println("【查询到的角色信息为:】\n"+role);

        /**
         * 测试修改
         */
        role.setRoleName("update-role-name-1");
        role.setRoleNote("update-role-note-1");
        roleMapper.updateRole(role);

        /**
         * 测试删除
         */
        roleMapper.deleteRole(role.getId());
    }

}

  运行该测试方法我们发现,当运行一个SqlSessionTemplate时,它就会重新获取一个新的SqlSession,也就是说每一个SqlSessionTemplate运行的时候会产生新的SqlSession,所以每一个方法都是独立的SqlSession,这意味着它是线程安全的。

  SqlSessionTemplate需要使用字符串表明运行哪一个SQL,字符串不包括业务含义,只是功能性代码,并不符合面向对象的规范。与此同时,使用字符串时,IDE无法检测代码逻辑的正确性,所以这样的用法逐渐被开发者抛弃了。

  最后值得注意的是SqlSessionTemplate允许配置执行器的类型,当同时配置SqlSessionFactory和SqlSessionTemplate的时候,SqlSessionTemplate的优先级大于SqlSessionFactory。