MyBatis 的强大特性之一便是它的动态 SQL。
动态SQL就是指根据不同查询条件,生成不同的SQL语句。
MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
if
参数test:里面的表达式如果为ture则执行,否则不执行。
if(title != null)
<if test="title != null">
AND title like #{title}
</if>
choose
有时我们不想应用到所有的条件语句,而只想从中择其一项。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
switch (exp){
case 1:
break;
case 2:
break;
}
</select>
trim[where,set]
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
where id=#{id}
</update>
<trim prefix="SET" suffixOverrides=",">
...
</trim>
foreach
<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
代码测试
测试模糊查询
//模糊查询,可以通过自定义条件查询
List<User> getUserByLike(Map<String,Object> map);
接口编写
映射文件编写
<select id="getUser" resultType="User">
select * from mybatis.user
</select>
<select id="getUserByLike" resultType="User" parameterType="Map">
select * from mybatis.user
<where>
<if test="name!=null">
name like CONCAT('%',#{name},'%')
</if>
<if test="id!=null">
and id = #{id}
</if>
</where>
</select>
测试类
@Test
public void getUserByLike(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
Map<String,Object> map = new HashMap<String,Object>();
map.put("name","秦");
map.put("id",1);
List<User> users = mapper.getUserByLike(map);
for (User user : users) {
System.out.println(user);
}
}
注意:太过复杂的逻辑不建议使用动态SQL,简单的话可以直接使用动态SQL实现;
缓存
如果开启缓存,
在mapper映射文件中,添加一个标签
<!--开启缓存-->
<cache/>
如果要CRUD操作要查询结果需要缓存,可以使用usrCache;
<!--
useCache: 是否开启缓存
使用缓存可以解决问题:
查询出来的结果暂时保存着,消耗内存资源;
如果短时间查询同样的语句比较多,可以提高速度;
-->
<select id="getUser" resultType="User" useCache="true">
select * from mybatis.user
</select>