SqlSessionTemplate是个线称安全的类,每运行一个SqlSessionTemplate时,它就会重新获取一个新的SqlSession,所以每个方法都有一个独立的SqlSession,这意味着它是线称安全的。
上一篇文章已经介绍过MyBatis-Spring项目的搭建过程,本节按照前面介绍的流程,通过SqlSessionTemplate实现数据库的增删改差。
第一步:创建spring-mybatis.xml文件并配置数据源
这里使用DBCP数据库连接池的方式:
1 2 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 3 <property name="driverClassName" value="org.postgresql.Driver" /> 4 <property name="url" value="jdbc:postgresql://localhost:5433/postgres" /> 5 <property name="username" value="postgres" /> 6 <property name="password" value="postgres" /> 7 8 <property name="maxActive" value="100" /> 9 10 <property name="maxIdle" value="5" /> 11 12 <property name="maxWait" value="10000" /> 13 bean>
第二步:配置SqlSessionFactory
1 2 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 3 4 <property name="dataSource" ref="dataSource" /> 5 6 <property name="configLocation" value="mybatis-config2.xml" /> 7 bean>
mybatis-config2.xml的配置如下:
1 xml version="1.0" encoding="UTF-8"?> 2 DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 6 <configuration> 7 8 <settings> 9 10 <setting name="cacheEnabled" value="true" /> 11 12 <setting name="lazyLoadingEnabled" value="false" /> 13 14 <setting name="multipleResultSetsEnabled" value="false" /> 15 16 <setting name="useColumnLabel" value="true" /> 17 18 <setting name="useGeneratedKeys" value="false" /> 19 20 <setting name="autoMappingBehavior" value="PARTIAL" /> 21 22 <setting name="defaultExecutorType" value="SIMPLE" /> 23 24 25 26 27 28 <setting name="safeRowBoundsEnabled" value="false" /> 29 30 <setting name="mapUnderscoreToCamelCase" value="true" /> 31 32 <setting name="localCacheScope" value="SESSION" /> 33 34 <setting name="jdbcTypeForNull" value="OTHER" /> 35 36 <setting name="lazyLoadTriggerMethods" value="equals" /> 37 settings> 38 39 40 <typeAliases> 41 42 <package name="com.hyc.pojo" /> 43 <package name="com.hyc.objectfactory" /> 44 <package name="com.hyc.bean" /> 45 <package name="com.hyc.dao" /> 46 typeAliases> 47 48 49 50 <mappers> 51 <mapper resource="com/hyc/mapper/ProductMapper.xml" /> 52 mappers> 53 54 configuration>
因为里面配置了映射器,所以下一步需要创建映射器。在创建映射器之前,还要配置SqlSessionTemplate,其配置如下:
1 2 <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> 3 4 <constructor-arg ref="sqlSessionFactory" /> 5 6 <constructor-arg value="BATCH" /> 7 bean>
详细配置看注释。注意⚠️:数据源、sqlSessionFactory、sqlSessionTemplate都是配置在spring配置文件spring-mybatis.xml中。
第三步:创建mapper
1⃣️创建接口:ProductMapper.java
1 public interface ProductMapper { 2 3 int insertProduct(Product product); 4 5 int deleteByPrimaryKey(String id); 6 7 int updateByPrimaryKey(Product product); 8 9 ListselectProducts(String name); 10 11 }
2⃣️创建mapper:ProductMapper.xml
1 xml version="1.0" encoding="UTF-8"?> 2 DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <mapper namespace="com.hyc.dao.ProductMapper"> 4 <resultMap id="BaseResultMap" type="com.hyc.pojo.Product"> 5 <id column="id" jdbcType="VARCHAR" property="id" /> 6 <result column="product_name" jdbcType="VARCHAR" property="productName" /> 7 <result column="product_price" jdbcType="VARCHAR" property="productPrice" /> 8 <result column="product_type" jdbcType="VARCHAR" property="productType" /> 9 resultMap> 10 <sql id="Base_Column_List"> 11 id, product_name, product_price, product_type 12 sql> 13 14 15 <select id="selectProducts" resultMap="BaseResultMap" parameterType="String"> 16 select * from product where product_name like concat('%',#{name},'%') 17 select> 18 19 20 <insert id="insertProduct" parameterType="com.hyc.pojo.Product"> 21 insert into product 22 (id, 23 product_name, product_price, 24 product_type) 25 values 26 (#{id,jdbcType=VARCHAR}, #{productName,jdbcType=VARCHAR}, 27 #{productPrice,jdbcType=VARCHAR}, 28 #{productType,jdbcType=VARCHAR}) 29 insert> 30 31 32 <delete id="deleteByPrimaryKey" parameterType="java.lang.String"> 33 delete from 34 product 35 where id = #{id,jdbcType=VARCHAR} 36 delete> 37 38 39 <update id="updateByPrimaryKey" parameterType="com.hyc.pojo.Product"> 40 update product 41 set 42 product_name = #{productName,jdbcType=VARCHAR}, 43 product_price = 44 #{productPrice,jdbcType=VARCHAR}, 45 product_type = 46 #{productType,jdbcType=VARCHAR} 47 where id = #{id,jdbcType=VARCHAR} 48 update> 49 mapper>
在mapper中实现数据库的增删改差操作
第四步:创建单元测试:
1⃣️先创建一个基类初始化SqlSessionTemplate
1 public class BaseTest { 2 3 public SqlSessionTemplate template = null; 4 ClassPathXmlApplicationContext context = null; 5 6 @Before 7 public void before() { 8 context = new ClassPathXmlApplicationContext("classpath:spring-mybatis.xml"); 9 template = context.getBean(SqlSessionTemplate.class); 10 } 11 12 }
2⃣️创建测试类
1 public class TestSqlSessionTemplate extends BaseTest { 2 3 @Test 4 public void testInsert() { 5 Product product = (Product) super.context.getBean("product"); 6 String sql = "com.hyc.dao.ProductMapper.insertProduct"; 7 int add = super.template.insert(sql, product); 8 System.out.println(add > 0 ? "插入成功" : "插入失败"); 9 } 10 11 @Test 12 public void testDelete() { 13 String sql = "com.hyc.dao.ProductMapper.deleteByPrimaryKey"; 14 int del = super.template.delete(sql, "2"); 15 System.out.println(del > 0 ? "删除成功" : "删除失败"); 16 } 17 18 @Test 19 public void testUpdate() { 20 String sql = "com.hyc.dao.ProductMapper.updateByPrimaryKey"; 21 Product product = (Product) super.context.getBean("product"); 22 product.setProductName("test"); 23 product.setProductPrice("4000"); 24 product.setProductType("test"); 25 int update = super.template.update(sql, product); 26 System.out.println(update > 0 ? "修改成功" : "修改失败"); 27 } 28 29 @Test 30 public void testSelect() { 31 String sql = "com.hyc.dao.ProductMapper.selectProducts"; 32 Listproduts = super.template.selectList(sql, "衬"); 33 System.out.println(produts.size()); 34 } 35 }
下面一个一个执行查看测试结果,结果我就不贴出来了,肯定是要成功的结果,下面说一个测试过程中的问题吧:就是我插入、删除、更新都成功了,但返回的不是成功的条数,而是个负数-2147482646,经过查阅资料,网上都说是因为处理器类型导致的,我在配置中设置的mybatis处理器类型是BATCH,也就是批量,当我把它改成SIMPLE之后就成功了。
总结:其实从上测试中来看,使用SqlSessionTemplate获取mapper中的sql时想需要传一个字符串,这个字符串由mapper文件中的命名空间+方法ID组成,当使用字符串时IDE无法检查代码的逻辑性,而且也很容易出错,所以其实这种用法已经被更好的方法替代了,开发过程中也很少会使用这种方式,下一篇将会介绍更好的实现方式。