本文共 2187 字,大约阅读时间需要 7 分钟。
hibernate中的缓存分两大类:一级、二级、查询
Why那么为什么要使用缓存呢?
为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。
缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。
What
一级缓存:一个线程对应一个session,一个线程可以看成一个用户。也就是说session级缓存(一级缓存)只能给一个线程用,别的线程用不了,一级缓存就是和线程绑定了。也成为session级的缓存或事务级缓存,生命周期短,用来缓存实体对象,不会被共享,其中load/get/iterate支持一级缓存,以load方法为例:
二级缓存:进程级缓存或SessionFactory级缓存,有可能出现并发问题,因此需要采用适当的并发访问策略,该策略为被缓存的数据提供了事务隔离级别其生命周期和SessionFactory一致,二级缓存可以被所有session共享
那么什么情况下适用二级缓存呢?
1) 很少被修改的数据 2) 不是很重要的数据,允许出现偶尔并发的数据 3) 不会被并发访问的数据 4) 常量数据
查询缓存:一级缓存和二级缓存都只是存放实体对象的,如果查询实体对象的普通属性的数据,只能放到查询缓存里,查询缓存还存放查询实体对象的id。查询缓存的生命周期不确定,当它关联的表发生修改,查询缓存的生命周期就结束。这里表的修改指的是通过hibernate修改,并不是通过数据库客户端软件登陆到数据库上修改。
true
hibernate的查询缓存默认是关闭的,如果要使用就要到hibernate.cfg.xml文件里配置:
How
1、一级缓存
evit(Object obj) 将指定的持久化对象从一级缓存中清除,释放对象所占用的内存资源,指定对象从持久化状态变为脱管状态,从而成为游离对象。
clear() 将一级缓存中的所有持久化对象清除,释放其占用的内存资源。
contains(Object obj) 判断指定的对象是否存在于一级缓存中。
flush() 刷新一级缓存区的内容,使之与数据库数据保持同步。
应用:
public void testCache1() { Session session = null; try {
session = HibernateUtils.getSession(); session.beginTransaction();//开启事务 Student student = (Student) session.load(Student.class, 1); System.out.println("student.name=" + student.getName()); student = (Student) session.load(Student.class, 1); System.out.println("student.name=" + student.getName()); session.getTransaction().commit();//事务提交 } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback();//事务回滚 } finally { HibernateUtils.closeSession(session);//关闭Session } }
2、二级缓存 org.hibernate.cache.EhCacheProvider true
存在一对多的关系,想要在在获取一方的时候将关联的多方缓存起来,需要在集合属性下添加<cache>子标签,这里需要将关联的对象的hbm文件中必须在存在<class>标签下也添加<cache>标签,不然Hibernate只会缓存OID。
转载地址:http://zvqko.baihongyu.com/