Mybatis 坑路4 -> 基于 XML 配置映射器2

32 篇文章 0 订阅
6 篇文章 0 订阅

基于 XML 配置映射器

配置动态 SQL

处理枚举类型

处理 CLOB/BLOB 类型

传入多个输入参数

缓存

集成 Ehcache

配置动态 SQL

  有时候,静态的 SQL 语句并不能满足应用程序的需求。我们可以根据一些条件,来动态地构建 SQL 语句。
  例如,在 Web 应用程序中,有可能有一些搜索界面,需要输入一个或多个选项,然后根据这些已选择的条件去执行检索操作。在实现这种类型的搜索功能,我们可能需要根据这些条件来构建动态的 SQL 语句。如果用户提供了任何输入条件,我们需要将那个条件添加到 SQL 语句的 WHERE 子句中。
  MyBatis 通过使用<if>,<choose>,<where>,<foreach>,<trim>元素提供了对构造动态 SQL 语句的高级别支持。
  <if>元素被用来有条件地嵌入 SQL 片段,如果测试条件被复制为 true。则相应的 SQL 片段将会被添加到 SQL 语句中。

SELECT * FROM COURSES WHERE TUTOR_ID=#{tutorId}
<if test="courseName != null">
	AND NAME LIKE #{courseName}
</if>
<if test="startDate != null">
	AND START_DATE &gt;#{startDate}
</if>
<if test="endDate != null">
	<![CDATA[ AND END_DATE <= #{endDate}]]>
</if>

<select id="searchCourses" parameterType="hashmap" resultMap="CourseResult">
	SELECT * FROM COURSES
	<choose>
		<when test="searchBy == 'Tutor'">
			WHERE TUTOR_ID = #{tutorId}
		</when>
		<when test="searchBy == 'CourseName'">
			WHERE name like #{courseName}
		</when>
		<otherwise>
			WHERE TUTOR start_date >= now()
		</otherwise>
	</choose>
</select>

  MyBatis 计算 <choose> 测试条件的值,且使用第一个值为 TRUE 的子句。如果没有条件为 true,则使用<otherwise>内的子句。
  有时候,所有的查询条件应该是可选的。在需要使用至少一种查询条件的情况下,我们应该使用 WHERE 子句。并且,如果有多个条件,我们需要在条件中添加 AND 或 OR。MyBatis 提供了<where>元素支持这种类型的动态 SQL 语句。

SELECT * FROM COURSES
<where>
	<if test="tutorId != null">
		AND TUTOR_ID = #{tutorId}
	</if>
	<if test="courseName != null">
		AND NAME LIKE #{courseName}
	</if>
	<if test="startDate != null">
		AND START_DATE &gt;= #{startDate}
	</if>
</where>

  <trim>元素和<where>元素类似,但是<trim>提供了在添加前缀/后缀或者移出前缀/后缀方面提供更大的灵活性。

SELECT * FROM COURSES
<trim prefix="WHERE" prefixOverrides="AND|OR">
	<if test="tutorId != null">
		TUTOR_ID = #{tutorId}
	</if>
	<if test="courseName != null">
		AND NAME LIKE #{courseName}
	</if>
</trim>

  这里如果任意一个<if>条件为 true,<trim>元素会插入 WHERE,并且移出紧跟 WHERE 后面的 AND 或者 OR
<foreach>可以迭代遍历一个数组或者列表,构造 AND/OR 条件或一个 IN 子句。

SELECT * FROM COURSES
<if test="tutorIds != null">
	<where>
		<foreach item="tutorId" collection="tutorIds">
			OR TUTOR_ID = #{tutorId}
		</foreach>
	</where>
</if>

  <set>元素和<where>元素类似,如果其内部条件判断有任何内容返回时,他会插入 SET SQL 片段

UPDATE STUDENTS
<set>
	<if test="name != null">name=#{name},</if>
	<if test="email != null">email=#{email},</if>
	<if test="phone != null">phone=#{phone},</if>
</set>
WHERE STUD_ID = #{id}

  如果<if>条件返回了任何文本内容,<set>将会插入 set 关键字和其文本内容,并且会剔除末尾的“,”

处理枚举类型

  MyBatis 支持开箱方式持久化 enum 类型属性。假设 STUDENTS 表中有一列 gender 存储 “MALE” 或者 “FEMALE” 两种值。并且,Student 对象有一个 enum 类型的 gender 属性。
  默认情况下,MyBatis 使用 EnumTypeHandler 类处理 enum 类型的 Java 属性,并且将其存储为 enum 值的名称。且不需要为此做任何额外的配置,就可以像使用基本数据类型属性一样使用 enum 类型属性。
  如果你希望存储原 enum 的顺序位置,而不是 enum 名,则需要明确地配置它。需要在 mybatis-config.xml 文件中配置 EnumOrdinalTypeHandler:

<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="xx.mybatis3.domain.Gender" />

处理 CLOB/BLOB 类型

  MyBatis 提供了内建的对 CLOB/BLOB 类型列的映射处理支持。默认情况下,MyBatis 将 CLOB 类型的列映射到 java.lang.String 类型上、而把 BLOB 列映射到 byte[] 类型上。

####传入多个输入参数
  MyBatis 中的映射语句有一个 parameterType 属性来制定输入参数的类型。如果我们想给映射语句传入多个参数的话,可以将所有的输入参数放到 HashMap 中,将 HashMap 传递给映射语句。
  MyBatis 还提供了另外一种传递多个输入参数给映射语句的方法。假设我们想通过给定的 name 和 email 信息查找学生信息,定义查询接口如下:

List<Student> findAllStudentByNameAndEmail(String name,String email);

<select id="findAllStudentByNameAndEmail" resultMap="StudentResult">
	SELECT STUD_ID,NAME,EMAIL,PHONE FROM STUDENTS WEHRE NAME=#{param1} AND EMAIL=#{param2}
</select>

  这里的 #{param1} 引用第一个参数 name,而 #{param2} 引用了第二个参数 email。

  MyBatis 还提供了一种传递多个输入参数给映射语句的方法。是通过使用 @Param 注解:

List<Student> findAllStudentByNameAndEmail(@Param("name")String name,@Param("email")String email);

<select id="findAllStudentByNameAndEmail" resultMap="StudentResult">
	SELECT STUD_ID,NAME,EMAIL,PHONE FROM STUDENTS WHERE NAME=#{name} AND EMAIL=#{email}
</select>

缓存

  将从数据库中加载的数据缓存到内存中,是很多应用程序为了提高性能而采取的一贯做法。MyBatis 对通过映射的 SELECT 语句加载的查询结果提供了内建的缓存支持。默认情况下,启用一级缓存:即,一级缓存基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 SqlSession,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清除。
  我们可以在 SQL 映射器 XML 配置文件中使用 <cache />元素添加全局二级缓存。其存储作用域为 Mapper(Namespace)。
  当加入了<cache />元素,将会出现以下情况:

所有的在映射语句文件定义的<select>语句的查询结果都会被缓存
所有的在映射语句文件定义的<insert>,<update>和<delete>语句将会刷新缓存
缓存根据最近最少被使用(Least Recently Used,LRU)算法管理
缓存不会被任何形式的基于时间表的刷新(没有刷新时间间隔),即不支持定时刷新机制
缓存将存储 1024 个查询方法返回的列表或者对象的引用
缓存会被当作一个读/写缓存。这是指检索出的对象不会被共享,并且可以被调用者安全地修改,不会受其他潜在的调用者或者线程的潜在修改干扰。(即,缓存是线程安全的)

  也可以通过复写默认属性来自定义缓存的行为:

<chache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />
  • eviction:此处定义缓存的移出机制。默认值是 LRU,其可能的值有:LRU(least recently used,最近最少使用),FIFO(first in first out,先进先出),SOFT(soft reference,软引用),WEAK(weak reference,弱引用)。
    flushInterval:定义缓存刷新间隔,以毫秒计。默认情况下不设置。所以不使用刷新间隔,缓存 cache 只有调用语句的时候刷新。
  • size:此表示缓存 cache 中能容纳的最大元素数。默认值是 1024,你可以设置成任意的正整数。
  • readOnly:一个只读的缓存 cache 会对所有的调用者返回被缓存对象的同一个实例(实际返回的是被返回对象的一份引用)。一个读/写缓存 cache 将会返回被返回对象的一份拷贝(通过序列化)。默认情况下设置为 false。可能的值有 false 和 true。

  默认的映射语句的 cache 配置如下:

<select... flushCache="false" userCache="true" />
<insert... flushCache="true" />
<update... flushCache="true" />
<delete... flushCache="true" />

MyBatis 使用 Ehcache 缓存

  官网上提供了一个 MyBatis-ehcache.jar 的包用于整合 ehcache 缓存,文档中还说明需要一个 ehcache-core.jar 的包,除了这两个包之外有几个包也是必须的,官方并没有说明,以下是需要加入的所有和 ehcache 相关的包:

1.ehcache-core-2.4.4.jar
2.mybatis-ehcache-1.0.0.jar
3.slf4j-api-1.6.1.jar
4.slf4j-log4j12-1.6.2.jar

当然也可以直接在 Maven 构建工具中使用

<dependency>
	<groupId>org.mybatis.caches</groupId>
	<artifactId>mybatis-ehcache</artifactId>
	<version>1.1.0</version>
</dependency>

  新建一个 Ehcache 的配置文件,该文件名必须为 ehcache.xml,放在类路径下面。
  Sql mapper 配置文件里面加入以下内容(二选一)

<cache type="org.mybatis.caches.ehcache.LoggingEhcache" />会输出日志
<cache type="org.mybatis.caches.ehcache.EhcacheCache" />不会输出日志

Ehcache 配置文件示例:http://ehcache.org/ehcache.xml

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值