缓存的特点
特点:
-
将数据保存再内存中
常用的缓存服务器:
-
MongoDB
-
Redis
关键点:
Mybatis
提供了一级缓存和二级缓存的支持,默认情况下只开启一级缓存
一级缓存
特点:
-
基于
PerpetualCache
(Mybatis
自带的)的HashMap
本地缓存 -
session flush或者close
之后该session
中的所有cache
就会被清空
Mybatis的缓存机制
机制说明:
-
参数和
SQL
完全一样的情况下使用同一个SqlSession
对象调用同一个mapper
的方法只执行一次SQL
-
该
Session
第一次查询以后Mybatiss
会将其放在缓存当中。再次查询如果没有刷新并且缓存没有超时的情况下直接取缓存的数据而不会查询数据库
关键点:
由于Sqlsession
相互隔离,如果使用不同的Sqlsession
对象调用相同的mapper
、参数、方法时
Mybatis
还是会再次发送SQL
到数据库执行。
示例
WebsiteMapper
接口:
package com.junkingboy.mapper;
import com.junkingboy.bean.Student;
import com.junkingboy.bean.User;
import com.junkingboy.bean.Website;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.type.JdbcType;
import java.util.List;
import java.util.Map;
/**
* @description:mybatis框架测试接口,该接口定义了.xml文件操作的表用到的方法
* @data: 2021/11/2 16:35
* @author: Lucifer
*/
public interface WebsiteMapper {
/* 使用mybatis中自带的一级缓存进行查询操作 */
Website selectWebsiteById(int id);
}
websiteMapper.xml
:
测试方法:
package com.junkingboy.test;
import com.junkingboy.bean.Website;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.io.InputStream;
/**
* @description:测试一级缓存的查询方法
* @data: 2021/11/11 18:45
* @author: Lucifer
*/
public class Test {
public static Logger logger = Logger.getLogger(Test.class);
public static void main(String[] args) throws IOException {
/* 根据配置文件构建 */
InputStream config = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(config);
SqlSession ss = ssf.openSession();
/* 通过Sqlsession接口对象执行sql语句 */
Website site = ss.selectOne("com.junkingboy.mapper.WebsiteMapper.selectWebsiteById", 1);
logger.debug("使用同一个Sqlsession再执行一次");
Website website = ss.selectOne("com.junkingboy.mapper.WebsiteMapper.selectWebsiteById", 1);
/* 使用二级缓存的时候Sqlsession调用了commit提交方法才会生效 */
ss.commit(); //--->提交Sqlsession
logger.debug("创建一个新的sqlsession对象再执行一次");
SqlSession ss2 = ssf.openSession();
Website site2 = ss2.selectOne("com.junkingboy.mapper.WebsiteMapper.selectWebsiteById", 1);
ss2.commit();
}
}
结果分析:
-
第一个
SqlSession
实际只发生过一次查询,而第二次查询就从缓存中取出了,也就是SqlSession
层面的一级缓存。 -
这个时候需要设置二级缓存。使得缓存在
SqlSessionFactory
层面上能够提供给各个SqlSession
对象共享。
二级缓存
二级缓存的特点:
-
全局缓存,作用域超出 session 范围之外,可以被所有 SqlSession 共享。
二级缓存的配置:
-
现在
mybatis-config.xml
中设置 -
再在
mapper
当中设置 -
对个别查询进行调整。单独设置
cache
mybatis-config.xml
全局缓存配置:
<settings>
<setting name="cacheEnable" value="true" />
</settings>
mapper
配置:
二级缓存的作用域是针对 mapper
的 namescape
而言,即只有再次在 namescape
内(com.junkingboy.mapper.WebsiteMapper
)的查询才能共享这个缓存
<mapper namespace="com.junkingboy.WebsiteMapper">
<!-- cache配置 -->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />
</mapper>
属性说明:
属性 | 说明 |
---|---|
eviction | 代表的是缓存回收策略,目前 MyBatis 提供以下策略。LRU:使用较少,移除最长时间不用的对象;FIFO:先进先出,按对象进入缓存的顺序来移除它们;SOFT:软引用,移除基于垃圾回收器状态和软引用规则的对象;WEAK:弱引用,更积极地移除基于垃圾收集器状态和弱引用规则的对象。 |
flushInterval | 刷新间隔时间,单位为毫秒,这里配置的是 100 秒刷新,如果省略该配置,那么只有当 SQL 被执行的时候才会刷新缓存。 |
size | 引用数目,正整数,代表缓存最多可以存储多少个对象,不宜设置过大。设置过大会导致内存溢出。这里配置的是 1024 个对象。 |
readOnly | 只读,默认值为 false,意味着缓存数据只能读取而不能修改,这样设置的好处是可以快速读取缓存,缺点是没有办法修改缓存。 |
针对个别查询修改缓存:
<select id="getWebsiteList" resultType="net.biancheng.po.Website" usecache="true">
...
</select>
小结
-
Mybatis专心做的应该是 SQL 映射。
-