Java学习总结--063 MyBatis的特性动态SQL & 缓存

本文深入探讨了MyBatis框架中的动态SQL功能,包括if、choose、trim和foreach等元素的使用,以及如何通过OGNL表达式实现条件判断和循环,提升SQL语句的灵活性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值