Mybatis学习总结(五).动态SQL与Mybatis缓存

本文详细介绍了MyBatis的动态SQL功能及其应用案例,包括if、choose、where、set和foreach等元素的使用方法。同时,还探讨了一级缓存和二级缓存的工作原理及配置方式。

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

MyBatis 的一个强大的特性之一通常是它的动态 SQL 能力。提供了OGNL表达式动态生成SQL的功能。动态SQL有:
  • 1、if
  • 2、choose, when, otherwise
  • 3、where, set
  • 4、foreach

if

需求1:查询男性用户,如果输入了姓名,进行模糊查找。

/**
 * 测试动态sql
 * 查询男性用户,如果输入了姓名,进行模糊查找。
 * @param name
 * @return
 */
public List<User> queryUserLikeName(@Param("name") String name);

<select id="queryUserLikeName" resultType="User">
	SELECT * FROM tb_user WHERE sex = 1 
	<if test="name !=null and name != ''">
		AND name LIKE '%${name}%'
	</if>
</select>

测试1:
@Test
public void testQueryUserLikeName(){
    List<User> users = this.userMapper.queryUserLikeName("张");
    for (User user : users) {
        System.out.println(user);
    }
}
结果:


测试2:
@Test
public void testQueryUserLikeName(){
    List<User> users = this.userMapper.queryUserLikeName(null);
    for (User user : users) {
        System.out.println(user);
    }
}

结果:



choose, when, otherwise

需求2:查询男性用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找。

/**
 * 查询男性用户,如果输入了姓名则按照姓名模糊查找,否则如果输入了年龄则按照年龄查找。
 * 
 * @param name
 * @param age
 * @return
 */
public List<User> queryUserLikeNameAndAge(@Param("name") String name, @Param("age") Integer age);

<select id="queryUserLikeNameAndAge" resultType="User">
	SELECT * FROM tb_user WHERE sex = 1 
	<choose>
		<when test="age !=null and age != ''">
			AND age < #{age}
		</when>
		<when test="name !=null and name != ''">
			AND name LIKE '%${name}%'
		</when>
	</choose>
</select>

测试:
@Test
public void testQueryUserLikeNameAndAge(){
    List<User> users = this.userMapper.queryUserLikeNameAndAge("张",null);
    for (User user : users) {
        System.out.println(user);
    }
}

结果:


where, set

作用:完成WHERESET关键字,并且处理SQL语句的中语法错误

where测试:

需求3:查询所有用户,如果输入了姓名,进行模糊查找,如果输入了年龄则按照年龄查找。

/**
 * 查询所有用户,如果输入了姓名,进行模糊查找,如果输入了年龄则按照年龄查找。
 * 
 * @param name
 * @return
 */
public List<User> queryUserLikeName2(@Param("name") String name, @Param("age") Integer age);

<select id="queryUserLikeName2" resultType="User">
	SELECT * FROM tb_user
	<where>
		<if test="name !=null and name != ''">
			AND name LIKE '%${name}%'
		</if>
		<if test="age !=null and age != ''">
			AND age < #{age}
		</if>
	</where> 
</select>

测试:

 @Test
    public void testQueryUserLikeName2(){
        List<User> users = this.userMapper.queryUserLikeName2(null,30);
        for (User user : users) {
            System.out.println(user);
        }
    }

结果:


SET测试:

更新数据
/**
 * 更新user数据
 * 
 * @param user
 */
public void updateUser2(User user);

<update id="updateUser2" parameterType="cn.zto.mybatis.pojo.User">
	UPDATE tb_user
	<set>
		<if test="userName != null and userName != ''">
			user_name = #{userName},
		</if>
		<if test="age != null and age != ''">
			age = #{age},
		</if>
		<if test="password != null and password != ''">
			password = #{password},
		</if>
	</set> 
	WHERE
		id = #{id}
</update>

测试:
@Test
public void testUpdateUser2() {
    User user = this.userMapper.queryUserById(2L);
    user.setAge(35);
    user.setPassword(null);
    this.userMapper.updateUser2(user);
}

结果:

foreach

需求4:按照多个ID查询用户信息。

/**
 * 按照多个ID查询用户信息。
 * 
 * @param name
 * @return
 */
public List<User> queryUserByIds(@Param("ids") List<Long> ids);

<select id="queryUserByIds" resultType="User">
	SELECT * FROM tb_user WHERE id IN
	<foreach collection="ids" item="id" open="(" close=")" separator=",">
		#{id}
	</foreach>
</select>

测试:
@Test
public void testQueryUserByIds(){
    List<Long> ids = new ArrayList<Long>();
    ids.add(1L);
    ids.add(2L);
    ids.add(3L);
    List<User> users = this.userMapper.queryUserByIds(ids);
    for (User user : users) {
        System.out.println(user);
    }
}

结果:



缓存:一级缓存


Mybatis的一级缓存的作用域是session,当openSession()后,如果执行相同的SQL(相同语句和参数),Mybatis不进行执行SQL,而是从缓存中命中返回。


原理:
Mybatis执行查询时首先去缓存区命中,如果命中直接返回,没有命中则执行SQL,从数据库中查询。

Mybatis中一级缓存是默认开启,并且无法关闭。

测试一级缓存:



一级缓存满足条件:

1、 同一个session

2、 相同的SQL和参数

 

 

使用session.clearCache()强制查询不缓存。


在执行insert、update、delete时会刷新缓存。



缓存:二级缓存

Mybatis的二级缓存的作用域是一个mapper的namespace,同一个namespace中查询sql可以从缓存中命中。

二级缓存是可以跨session的。

开启二级缓存:
在mapper.xml文件中加入 <cache /> 。







注意:在Mybatis-Config中有缓存的全局控制器(cacheEnabled),默认是开启的,所以无需手动开启。

 

也可以手动关闭二级缓存:



二级缓存关闭后,上面测试第二次查询将从数据库查询

在<cache />标签中还有其他一些参数,如下:


可以参考mybatis官方文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值