09_一级缓存与二级缓存

1 理解MyBatis缓存

正如大多数据持久层框架一样,MyBatis同样提供了一级缓存和二级缓存的支持。

1.1 一级缓存

基于PerpetualCache的HashMap本地缓存,其存储作用域是Session,当Session flush或close之后,该Session中所有的Cache就将清空。

1.2 二级缓存

二级缓存与一级缓存其机制是相同的,默认也是采用PerpetualCache,HashMap存储,不同在于其存储作用是Mapper(Namespace),并且可自定义存储源,如Ehcache

1.3 更新机制

对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存 Namespaces)的进行了CUD操作后,默认该作用域下所有select中的缓存将被clear

2 一级缓存

2.1 需求

根据id查询对应的用户记录对象

2.2 准备数据表和数据

  1. CREATE TABLE c_user(
  2. id INT PRIMARY KEY AUTO_INCREMENT,
  3. NAME VARCHAR(20),
  4. age INT
  5. );
  6. INSERT INTO c_user(NAME, age) VALUES(‘Tom‘, 12);
  7. INSERT INTO c_user(NAME, age) VALUES(‘Jack‘, 11);

2.3 创建表的实体类

  1. public class CUser implements Serializable{
  2. private int id;
  3. private String name;
  4. private int age;

2.4 userMapper.xml

  1. <select id="getUser" parameterType="int" resultType="CUser">
  2. select * from c_user where id=#{id}
  3. </select>
  4. <update id="updateUser" parameterType="CUser">
  5. update c_user set name=#{name}, age=#{age} where id=#{id}
  6. </update>

2.5 测试

2.5.1 默认情况下是开启一级缓存的

  1. @Test
  2. public void testCacheOne1() {
  3. SqlSessionFactory factory = MybatisUtils.getFactory();
  4. SqlSession session = factory.openSession();
  5. String statement = "cn.imentors.mybatis.test9.userMapper.getUser";
  6. CUser user = session.selectOne(statement, 1);
  7. System.out.println(user);
  8. //默认一级缓冲是开启的
  9. user = session.selectOne(statement, 1);
  10. System.out.println(user);
  11. System.out.println("----------------");
  12. session.close();
  13. }

2.5.2 通过执行session.clearCache()清空缓存

  1. @Test
  2. public void testCacheOne2() {
  3. SqlSessionFactory factory = MybatisUtils.getFactory();
  4. SqlSession session = factory.openSession();
  5. String statement = "cn.imentors.mybatis.test9.userMapper.getUser";
  6. CUser user = session.selectOne(statement, 1);
  7. System.out.println(user);
  8. //执行了session.clearCache(),清空缓存
  9. session.clearCache();
  10. user = session.selectOne(statement, 1);
  11. System.out.println(user);
  12. System.out.println("----------------");
  13. session.close();
  14. }

2.5.3 通过执行CUD操作,清空一级缓存

  1. @Test
  2. public void testCacheOne3() {
  3. SqlSessionFactory factory = MybatisUtils.getFactory();
  4. SqlSession session = factory.openSession();
  5. String statement = "cn.imentors.mybatis.test9.userMapper.getUser";
  6. CUser user = session.selectOne(statement, 1);
  7. System.out.println(user);
  8. //执行CUD操作
  9. session.update("cn.imentors.mybatis.test9.userMapper.updateUser", new CUser(1, "Tom", 13));
  10. session.commit();
  11. user = session.selectOne(statement, 1);
  12. System.out.println(user);
  13. System.out.println("----------------");
  14. session.close();
  15. }

2.5.4 不同session

  1. @Test
  2. public void testCacheOne4() {
  3. SqlSessionFactory factory = MybatisUtils.getFactory();
  4. SqlSession session = factory.openSession();
  5. String statement = "cn.imentors.mybatis.test9.userMapper.getUser";
  6. CUser user = session.selectOne(statement, 1);
  7. System.out.println(user);
  8. //不是同一个Session对象
  9. session.close();
  10. session = factory.openSession();
  11. user = session.selectOne(statement, 1);
  12. System.out.println(user);
  13. System.out.println("----------------");
  14. session.close();
  15. }

3 二级缓存

3.1 开启MyBatis的二级缓存,即在userMapper.xml,添加如下代码

  1. <mapper namespace="cn.imentors.mybatis.test9.userMapper">
  2. <cache/>
  • 为什么在userMapper.xml添加呢,因为二级缓存是以namespace为单位,也就是说,二级缓存的作用域是实体SQL对应的xml,二级缓存是映射文件级的

3.2 测试

  1. @Test
  2. public void testCacheTwo() {
  3. SqlSessionFactory factory = MybatisUtils.getFactory();
  4. SqlSession session1 = factory.openSession();
  5. SqlSession session2 = factory.openSession();
  6. String statement = "cn.imentors.mybatis.test9.userMapper.getUser";
  7. CUser user = session1.selectOne(statement, 1);
  8. session1.commit();
  9. System.out.println(user);
  10. user = session2.selectOne(statement, 1);
  11. session2.commit();
  12. System.out.println(user);
  13. }

3.3 补充说明

1. 映射语句文件中的所有select语句将会被缓存。

2. 映射语句文件中的所有insert,update和delete语句会刷新缓存。

3. 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。

4. 缓存会根据指定的时间间隔来刷新。

5. 缓存会存储1024个对象

  1. <cache
  2. eviction="FIFO" //回收策略为先进先出
  3. flushInterval="60000" //自动刷新时间60s
  4. size="512" //最多缓存512个引用对象
  5. readOnly="true"/> //只读

捐赠我们
    良师益友工作室一直在致力于帮助编程爱好更加快速方便地学习编程,如果您对我们的成果表示认同并且觉得对你有所帮助,欢迎您对我们捐赠^_^。

时间: 2024-11-13 06:39:07

09_一级缓存与二级缓存的相关文章

Hibernate一级缓存和二级缓存深度比较

1.什么是缓存 缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能.缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据. 缓存的介质一般是内存,所以读写速度很快.但如果缓存中存放的数据量非常大时,也会用硬盘作为缓存介质.缓存的实现不仅仅要考虑存储的介质,还要考虑到管理缓存的并发访问和缓存数据的生命周期. Hibernate的一级缓存是内置的,不能被卸载. Hiberna

myBatis学习(9):一级缓存和二级缓存

正如大多数持久层框架一样,MyBatis同样提供了一级缓存和二级缓存的支持 1. MyBatis一级缓存基于PerpetualCache的HashMap本地缓存,其存储作用域为 Session,默认情况下,一级缓存是开启状态的.当 Session flush(); 或 close(); 之后,该Session中的所有 Cache 就将清空. 2.MyBatis二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Nam

hibernate 一级缓存,二级缓存,查询缓存

1.一级缓存是session级的缓存,session结束即事务提交,session关闭,缓存清除.效果不大 get方式:一个session内,第二次查询不连数据库.适用于一级缓存 load方式:懒加载查询(查询时不执行sql,使用结果时才会执行sql),第二次查询不连数据库.适用于一级缓存 createQuery(hql).list():查询了整个list,第一次调用list()时,执行sql.第二次查询时,又执行了sql,说明不使用一级缓存.也就是不使用二级缓存    createQuery(

【转】hibernate缓存:一级缓存和二级缓存

什么是缓存? 缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器,其作用是为了减少应用程序对物理数据源访问的次数,从而提高了应用程序的运行性能.Hibernate在进行读取数据的时候,根据缓存机制在相应的缓存中查询,如果在缓存中找到了需要的数据(我们把这称做"缓存命 中"),则就直接把命中的数据作为结果加以利用,避免了大量发送SQL语句到数据库查询的性能损耗. 缓存策略提供商 提供了HashTable缓存,EHCache,OSCache,SwarmCac

Hibernate一级缓存和二级缓存具体解释

一.一级缓存二级缓存的概念解释 (1)一级缓存就是Session级别的缓存,一个Session做了一个查询操作,它会把这个操作的结果放在一级缓存中.假设短时间内这个 session(一定要同一个session)又做了同一个操作.那么hibernate直接从一级缓存中拿,而不会再去连数据库,取数据: (2)二级缓存就是SessionFactory级别的缓存,顾名思义.就是查询的时候会把查询结果缓存到二级缓存中,假设同一个sessionFactory 创建的某个session运行了同样的操作,hib

个人对一级缓存,二级缓存的初步理解

当数据量足够大时,我们队底层的历史库进行相关查询会花费相关大的时间. 做数据库优化,可以对底层历史库做一些抽取,过滤,整理出一些常用的.实时的数据,我们称之为实时库. 实时库通常放在内存之中,因为内存之中读取的速度远远大于磁盘中读取的速度. 以上的加速速度,我们将之理解为一级缓存. 二级缓存,是位于程序之中,我们对常用的查询语句,进行缓存,第二次直接从缓存中读取,效率更高.

一级缓存与二级缓存

Hibernate中提供了两级Cache,第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存.这一级别的缓存由hibernate管理的,一般情况下无需进行干预:第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围或群集范围的缓存.这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载. Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存. 一. 一级缓存和二级缓存的比较: 第一级缓存 第二级缓存 存放数据的形式相互关联的持久化对象 对象的散装

Hibernate一级缓存、二级缓存以及查询缓存的关系

转载自http://blog.csdn.net/maoyeqiu/article/details/50209893 前两天总结了一下二级缓存和查询缓存的关系,但是又有一个新的问题,就是查询缓存缓存到二级缓存的数据,在第三次(第一次缓存中没有数据,查询数据库将对应的ID值存入到二级缓存中去,第二次如果是同一个Session那么将会把数据一级缓存中的数据返回,如果不是同一个Session而是同一个sessionfactory,那么将会把二级缓存中的数据返回,同时将数据放入到一级缓存中去)获取的时候,

Mybatis中的一级缓存和二级缓存

1.概述 mybatis提供查询缓存主要是为了减轻了数据库的压力,提高了系统的性能. 缓存分为一级缓存和二级缓存,他们之间的关系和区别如下: 一级缓存是sqlSession级别的缓存.在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(hashmap)对象缓存数据.不同的sqlSession之间的数据缓存区域是不互相影响的. 二级缓存是mapper级别的缓存.多个sqlSession去操作同一个mapper中的sql语句,多个sqlSession共享同一个Mapper的二级缓