公众号merlinsea
简介:⼆级缓存是namespace级别的,多个SqlSession去操作同⼀个namespace下的Mapper的sql语句,同一个namespace下的多个SqlSession可以共⽤⼆级缓存,即同一个mapper标签下的CRUD语句共用二级缓存。
访问缓存的优点:数据库是基于磁盘来存放数据的,因此访问数据库的性能开销可以可以分为建立数据库连接+磁盘访问IO的开销;mybatis中的缓存是基于内存的,计算机访问内存的速度要远快于访问磁盘的速度,因此单位时间内通过内存来提供读数据服务要远快于通过磁盘来读取数据服务,提供的并发访问量级也会更高,这也是为什么要开启缓存的原因——提高并发访问量。
底层数据结构:基于PerpetualCache 的 HashMap本地缓存,和一级缓存一致。
默认不开启二级缓存。
缓存淘汰策略:当二级缓存空间满的时候会使⽤ LRU 算法来收回。
二级缓存失效情况:执⾏同个namespace下的mapepr映射⽂件中增删改sql,并执⾏了commit操作,会清空该⼆级缓存。
1、在mybatis的全局配置文件mybatis-config.xml中开启二级缓存总开关
<!--下划线自动映射驼峰字段--> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> <!--这个配置使全局的映射器(二级缓存)启用或禁用缓存,全局总开关,这里关闭,mapper中开启了也没用--> <setting name="cacheEnabled" value="true" /> </settings>
2、在mapper.xml文件中开启mapperc层的二级缓存
<mapper namespace="net.xdclass.online_class.dao.VideoMapper" <sql id="base_video_field"> id,title,summary,cover_img </sql> <!--在这个mapper下面的同一个namespace中开启二级缓存--> <cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/> <select id="selectById" parameterType="java.lang.Integer" resultType="Video"> select <include refid="base_video_field"/> from video where id = #{video_id,jdbcType=INTEGER} </select> </mapper>
3、使用二级缓存的demo
走二级缓存的条件:同一个namespace下的同一个sql语句。
public class SqlSessionCacheDemo { public static void main(String [] args) throws IOException { String resouce = "config/mybatis-config.xml"; //读取配置文件 InputStream inputStream = Resources.getResourceAsStream(resouce); //构建Session工厂 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //获取Session try{ /** * 第一次回去数据库中找,找到以后会放入二级缓存中 */ SqlSession sqlSession1 = sqlSessionFactory.openSession(); VideoMapper videoMapper1 = sqlSession1.getMapper(VideoMapper.class); Video video1 = videoMapper1.selectById(1); System.out.println(video1.toString()); sqlSession1.commit(); /** * 第二次由于是同一个namespace下的同一个sql语句,因此会走二级缓存 */ SqlSession sqlSession2 = sqlSessionFactory.openSession(); VideoMapper videoMapper2 = sqlSession2.getMapper(VideoMapper.class); Video video2 = videoMapper2.selectById(1); System.out.println(video2.toString()); sqlSession2.commit(); }catch (Exception e){ e.printStackTrace(); } } }