Hibernate缓存机制

こ雲淡風輕ζ 提交于 2020-01-20 02:29:52

Hibernate缓存机制

什么是缓存,为什么需要缓存?

  • 什么是缓存? 存在内存中的临时数据
  • 为什么需要缓存? 减少程序直接和数据库交互的次数,因为直接交互的结果集很多都是重复的,例如查询,缓存可以减少开销
  • 什么样的数据适合缓存?什么样的数据不适合缓存?
    • 适合缓存的数据 多次查询且很少次修改,同时修改了之后对结果的影响不大的数据
    • 不适合缓存的数据 并发访问的数据一定不能被缓存

Hibernate一级缓存验证

Hibernate一级缓存指的是Session对象的缓存,一旦Session对象销毁了,一级缓存也就消失了,下面代码证明了一级缓存的存在:

@Test
    public void test2(){
        Configuration cfg = new Configuration();
        cfg.configure();
        SessionFactory factory = cfg.buildSessionFactory();
        Session session = factory.openSession();
        Transaction tx = session.beginTransaction();
        
        //第一次查询,查询结果放到了一级缓存当中
        User user1 = (User) session.get(User.class, 95L);
        //第二次查询,先从一级缓存当中查询,有的话拿过来直接用,没有的话向数据库查询
        User user2 = (User) session.get(User.class, 95L);

        System.out.println(user1);
        System.out.println(user2);

        tx.commit();
        session.close();
        factory.close();
    }

运行的结果如下:

Hibernate: 
    select
        user0_.id as id0_0_,
        user0_.name as name0_0_,
        user0_.birthday as birthday0_0_ 
    from
        user user0_ 
    where
        user0_.id=?
com.ryan.User@25bfcafd
com.ryan.User@25bfcafd

可以看到,确实在一次查询且Session没有被关闭的情况下,Hibernate只向数据库查询了一次

Hibernate一级缓存的原理

Hibernate首先根据类的class字节码字符串来使查询映射到一个Map对象,这个Map对象的key是OID(Object ID),value是Object,由此可得到一级缓存的工作原理。

然而一级缓存还有一个快照区域,用来保存查询出来的对象数据,若快照区域的对象和一级缓存中的Session对象不一致的时候,会触发更新数据库的操作update()

Hibernate对象的四种状态

  • 瞬时状态(临时状态) 没有OID,和Session没有关系
  • 持久状态 有OID,和Session有关系,只有持久化状态的对象才有一级缓存!!!!!
  • 游离状态(托管状态) 有OID,与Session没关系
  • 删除状态 有OID,和Session有关系,但是调用了删除的方法,但是事务还没有提交,此时为删除态

Hibernate二级缓存

SessionFactory级别的二级缓存是全局性的,所有的Session可以共享这个二级缓存。不过二级缓存默认是关闭的,需要显示开启并指定需要使用哪种二级缓存实现类(可以使用第三方提供的实现)。一旦开启了二级缓存并设置了需要使用二级缓存的实体类,SessionFactory就会缓存访问过的该实体类的每个对象,除非缓存的数据超出了指定的缓存空间。

一级缓存和二级缓存都是对整个实体进行缓存,不会缓存普通属性,如果希望对普通属性进行缓存,可以使用查询缓存。查询缓存是将HQL或SQL语句以及它们的查询结果作为键值对进行缓存,对于同样的查询可以直接从缓存中获取数据。查询缓存默认也是关闭的,需要显示开启。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!