hibernate二级缓存注解-mybatis的二级缓存和hibernate的三级缓存

2022-12-29 09:07:28 浏览数 (1)

目录

缓存 一、缓存介绍

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

  1.一级缓存: 基于 的 本地缓存,其存储作用域为,当 flush 或 close之后,该中的所有 Cache 就将清空。

  2. 二级缓存与一级缓存其机制相同,默认也是采用 ,存储,不同在于其存储作用域为 Mapper(),并且可自定义存储源,如 。

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

  1.导包:

  2一级缓存代码

  (String[] args) {

   as = Test1.class.().("-config.xml");

   = ().build(as);

   = .();

   = .();

  Object obj1 = .("user.",1);

  Object obj2 = .("user.",1);

  System.out.(obj1);

  System.out.(obj2);

  //关闭

  .close();

  .close();

  }

  运行结果:

  3.二级缓存代码

  (String[] args) {

   as = Test1.class.().("-config.xml");

   = ().build(as);

  //开启两个不同的

   = .();

   = .();

  //使用二级缓存时,User类必须实现一个接口===> User

  Object obj1 = .("user.",1);

  .commit();//这个地方一定要提交事务之后二级缓存才会起作用

  Object obj2 = .("user.",1);

  System.out.(obj1);

  System.out.(obj2);

  //关闭

  .close();

  .close();

  }

  (String[] args) {

   as = Test1.class.().("-config.xml");

   = ().build(as);

  //开启两个不同的

   = .();

   = .();

  //使用二级缓存时,User类必须实现一个接口===> User

  Object obj1 = .("user.",1);

  .commit();//这个地方一定要提交事务之后二级缓存才会起作用

  Object obj2 = .("user.",1);

  System.out.(obj1);

  System.out.(obj2);

  //关闭

  .close();

  .close();

  }

  运行结果:

  4、二级缓存补充说明

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

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

  3. 缓存会使用Least Used(LRUhibernate二级缓存注解,最近最少使用的)算法来收回。

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

  5. 缓存会存储1024个对象

  cache标签常用属性:

   缓存 所有缓存机制详解

  提供的一级缓存

  是一个线程对应一个,一个线程可以看成一个用户。也就是说级缓存(一级缓存)只能给一个线程用,别的线程用不了,一级缓存就是和线程绑定了。

  一级缓存生命周期很短,和生命周期一样,一级缓存也称级的缓存或事务级缓存。如果tb事务提交或回滚了,我们称就关闭了,生命周期结束了。

  缓存和连接池的区别:缓 存和池都是放在内存里,实现是一样的,都是为了提高性能的。但有细微的差别,池是重量级的,里面的数据是一样的,比如一个池里放100个 连接对象,这个100个都是一样的。缓存里的数据,每个都不一样。比如读取100条数据库记录放到缓存里,这100条记录都不一样。

  1.导包

  2.一级缓存代码

  (String[] args) {

   cfg = ();

   = cfg.(".cfg.xml").();

   = .();

  User user = (User).get(User.class, 1);

  //第二次查询第一次相同的数据,第二次不会发出sql语句查询数据库,而是到缓存里取数据。

  User user2 = (User).get(User.class, 1);

  System.out.(user);

  System.out.(user2);

  //关闭释放一级缓存

  .close();

  .close();

  }

  运行结果:

  3.二级缓存代码

  (String[] args) {

   cfg = ();

   = cfg.(".cfg.xml").();

   = .();

   = .();

  User user1 =(User).load(User.class, 1);

  User user2 =(User) .load(User.class, 1);

  System.out.(user1.());

  System.out.(user2.());

  //关闭 释放二级缓存

  .close();

  .close();

  .close();

  }

  注:

  运行结果:

  可见,二级缓存是起作用了的。用get测试是同样的结果。

  4.三级缓存代码

  (String[] args) {

   cfg = ();

   = cfg.(".cfg.xml").();

   = .();

  Query query1 = .("FROM User");

  query1.(true);

  //List list1 = query1.list();

   = query1.();

  Query query2 = .("FROM User");

  query2.(true);

  //List list2 = query2.list();

   = query2.();

  System.out.();

  System.out.();

  //关闭 释放三级缓存

  .close();

  .close();

  }

  运行结果:

  5.一级缓存 二级缓存 三级缓存 之间的比较

  一级缓存(级的缓存):在一个中load同一个对象2次,load时,首先在缓存中查找对象,如果没找到就到数据库中去load。因此,在同一个中load一个对象2次,只会发出一条sql语句。而在2个中load同一个对象则会发送2次sql语句。

  二级缓存(的公用缓存,级别的缓存,jvm级缓存):支持多种二级缓存,提供了一个,用于测试,不建议运用与产品中。

  二级缓存适合放什么对象呢?

  ①经常被访问(这个对象经常被访问,如果每次都到数据库去取hibernate二级缓存注解,会降低效率)

  ②改动不大(这个对象改动不大,如果改动较大,就可能造成缓存数据跟数据库中的数据不一致)

  三级缓存(查询缓存):如果要使Query使用二级缓存,则需要打开查询缓存。事实上,三级缓存是基于二级缓存的,如:list(集合),默认情况,它只会往二级缓存中存放数据,查找时不会搜索二级缓存,这是因为查询条件会随时变化。有一种情况就是2次查询的条件是一样的,这是要想使用二级缓存,就必须打开查询缓存,打开方式如:

  true

  然后加上:(true)

  缓存算法有:

  LRU(Least Used):这种算法是在每个对象中维护一个访问的时间变量,每次访问后,时间都会更新,当新的对象需要存放到缓存时,替换那个按时间排序最后的对象。

  LFU(Least Used):这种算法是每个对象记录了对象访问的次数(即命中率),当新的对象需要存放到缓存时,替换那个访问次数最少的对象。

  FIFO(First In First Out):这种算法是将缓存中的对象存放成一个数组,当新的对象需要存放到内存中是,替换最先存放到缓存的对象。

  使用时通常在缓存配置文件中加入:olicy="LRU"。

  list和存放的不同之处:

  ①List:直接取出所有的记录将其封装成对象放到集合中。

  :先取出所有记录的id(主键),当需要用到对应的id的记录时,再根据id发sql语句。②list不会主动利用级的缓存,因此list遍历时每次会到数据库中取数据。

  会利用的缓存,每次会到缓存中找,如果缓存中没有,再到数据库中取数据。

  ③默认使用二级缓存

  list默认往二级缓存存数据,但是查询时不使用二级缓存。

本文共 1402 个字数,平均阅读时长 ≈ 4分钟

0 人点赞