Mybatis缓存
一级缓存特点:一级缓存默认开启,缓存范围仅限于一个SqlSession会话,即一个session对象,范围太小,声明周期短。两个session对象查询后,数据存储在不同的内存地址中。而且,commit提交后会强制清空namespace缓存,session对象缓存的查询数据就没了。为了合理提高缓存命中率,提高查询速度,使用二级缓存。
二级缓存特点:二级缓存的范围大,属于范围Mapper Namespace,周期长。需要设置catch标签。在一个namespace空间内,多个session对象执行同一个id的查询,查询后的数据放在一个缓存地址中。第一次从硬盘的数据库中查询数据,后面再次查询不再执行sql语句,直接从缓存中提取数据,速度更快。
一级缓存和二级缓存范围对比图
二级缓存的实现需要在命名空间内使用cache标签,它有四个设置项:
eviction是缓存的清除策略,当缓存对象数量达到上限后,自动触发对应算法对缓存对象清除
1.LRU – 最近最少使用的:移除最长时间不被使用的对象。
O1 O2 O3 O4 … O512
14 99 83 1 893
2.FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
3.SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
4.WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
flushInterval 代表间隔多长时间自动清空缓存,单位毫秒,600000毫秒 = 10分钟
size 缓存存储上限,用于保存对象或集合(1个集合里面有很多数据也算1个对象)的数量上限
readOnly 设置为true ,代表返回只读缓存,每次从缓存取出的是缓存对象本身.这种执行效率较高
设置为false , 代表每次取出的是缓存对象的"副本",每一次取出的对象都是不同的,这种安全性较高
使用规则:
1.二级开启后默认所有查询操作均使用缓存
2.写操作commit提交时对该namespace缓存强制清空
3.配置useCache=false可以不用缓存
4.配置flushCache=true代表强制清空缓存
动态SQL筛选实现
动态SQL:根据参数的数据动态组织SQL的技术。应用场景:比如淘宝的筛选商品功能
实现方法:使用if标签和where标签。
例:查询t_goods表格中,category_id是44,当前价格小于300的商品
<!-- 动态SQL实现,使用if标签和where标签实现,if标签中的test判断map中的某个key是否存在,存在就and添加一个条件 -->
<!-- where标签用<>包括起来,不是单纯的sql中的where,可以避免多个条件and连接问题 -->
<!-- 多个筛选条件有多个参数,使用Map接口实现,使用parameterType指定Map接口,SQL中#{
key}提取参数 -->
<select id="dynamicSQL" parameterType="java.util.Map" resultType="com.imooc.mybatis.entity.Goods">
select * from t_goods
<where>
<if test="categoryId != null">
and category_id = #{
categoryId}
</if>
<if test="currentPrice != null">
and current_price < #{
currentPrice}
</if>
</where>
</select>
查询t_goods表中,category_id是1,当前价格小于300的商品,测试类中的java代码为:
session = MyBatisUtils.openSession();
//map用来保存筛选条件
Map param = new HashMap();
param.put("categoryId", 1);
param.put("currentPrice", 300);
//查询
List<Goods> list = session.selectList("goods.dynamicSQL", param);
for (Goods g : list) {
System.out.println(g.getTitle() + ": " + g.getCategoryId(