标签:
1.Java中的缓存是指的是一组用于提高IO性能的内存地址,它位于JVM中,存储在内存或者磁盘中。
2. 为什么要用Hibernate缓存?
Hibernate是一个持久层框架,经常访问物理数据库。为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。缓存内的数据时对物理数据源中的数据的赋值,应用程序在运行时从缓存读写数据,如果缓存中不存在,才会去访问数据库。
3.Hibernate缓存分类
(1) 一级缓存:
是一个线程对应一个session,一个线程可以看成一个用户。也就是说session级缓存只能给一个线程用,别的线程用不了,大家不能共享,总之,一级缓存就是和线程绑定了。一级缓存的生命周期很短,和session生命周期一样,一级缓存也称session级的缓存或事务级的缓存。如果session关闭了,生命九期也就结束了。
(2) 二级缓存:
二级缓存也称为进程级的缓存或sessionFactory级的缓存。二级缓存可以被所有的session共享。二级缓存的生命周期和SessionFactory的生命周期一致,SessionFactory可以管理二级缓存。
(3)查询缓存:
查询缓存是缓存普通属性结果集的,对实体对象的结果集会缓存id。当关联的表发生修改,查询缓存的生命周期就结束了。
4. 一级缓存
对于Hibernate一级缓存时默认就有的,并且不能卸载。一级缓存的内部结构就是一个map<id,object>,map的key就是id,map 的value就是实体对象,所以一级缓存缓存的是实体对象,不能缓存属性。
hibernate是一个线程对应一个session,一个线程可以看成一个用户。也就是说session级缓存(一级缓存)只能给一个线程用,别的线程用不了,一级缓存就是和线程绑定了。hibernate一级缓存生命周期很短,和session生命周期一样,一级缓存也称session级的缓存或事务级缓存。如果tb事务提交或回滚了,我们称session就关闭了,生命周期结束了。
下面我们来看写一下测试代码:
classes类:
package com.lsh.hibernate; import java.util.Set; public class Classes { private int id; private String name; private Set students; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set getStudents() { return students; } public void setStudents(Set students) { this.students = students; } }
Junit测试类:
package com.lsh.hibernate; import java.io.Serializable; import java.util.Iterator; import org.hibernate.Session; import junit.framework.TestCase; public class CacheTest extends TestCase { /** * 在同一个session中发出两次load查询 */ public void testCache1(){ Session session =null; try { session =HibernateUtils.getSession(); session.beginTransaction(); Student student =(Student)session.load(Student.class, 10); System.out.println("student.name=" + student.getName()); //不会发出查询语句,load使用缓存 student=(Student)session.load(Student.class, 10); System.out.println("student.name=" +student.getName()); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtils.closeSession(session); } } /** * 在同一个session中发出两次get查询 */ public void testCache2(){ Session session =null; try { session =HibernateUtils.getSession(); session.beginTransaction(); Student student =(Student)session.get(Student.class, 1); System.out.println("student.name=" + student.getName()); //不会发出查询语句,get使用缓存 student=(Student)session.get(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中发出两次iterate查询,查询实体对象 */ public void testCache3(){ Session session =null; try { session =HibernateUtils.getSession(); session.beginTransaction(); Iterator iter = session.createQuery("from Student s where s.id<10").iterate(); while (iter.hasNext()) { Student student = (Student) iter.next(); System.out.println(student.getName()); } System.out.println("_______________________________"); //它会发出查询id的语句,但不会发出根据id查询学生的语句,因为iterate使用缓存 iter=session.createQuery("from Student s where s.id<10").iterate(); while (iter.hasNext()) { Student student = (Student) iter.next(); System.out.println(student.getName()); } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtils.closeSession(session); } } /** * 在两个session中发出iterate查询,查询普通属性 */ public void testCache4(){ Session session =null; try { session =HibernateUtils.getSession(); session.beginTransaction(); Iterator iter = session.createQuery("select s.name from Student s where s.id<5").iterate(); while (iter.hasNext()) { String name = (String) iter.next(); System.out.println(name); } System.out.println("_______________________________"); //iterate查询普通属性,一级缓存不会缓存,所以发出查询语句 //一级缓存是缓存实体对象的 iter=session.createQuery(" select s.name from Student s where s.id<5").iterate(); while (iter.hasNext()) { String name = (String) iter.next(); System.out.println(name); } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtils.closeSession(session); } } /** * 在同二个session中发出load查询 */ public void testCache5(){ Session session =null; try { session =HibernateUtils.getSession(); session.beginTransaction(); Student student =(Student)session.load(Student.class, 10); System.out.println("student.name=" + student.getName()); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtils.closeSession(session); } try { session =HibernateUtils.getSession(); session.beginTransaction(); //会发出查询语句,session间不能共享一级缓存数据 //因为他会伴随着session的消亡而消亡 Student student =(Student)session.load(Student.class, 10); System.out.println("student.name=" + student.getName()); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtils.closeSession(session); } } /** * 在同一个session中先调用save,再调用load查询刚刚save的数据 */ public void testCache6(){ Session session=null; try { session=HibernateUtils.getSession(); session.beginTransaction(); Student student =new Student(); student.setName("张三"); Serializable id =session.save(student); student=(Student)session.load(Student.class, id); //不会发出查询语句,因为save支持缓存 System.out.println("student.name=" + student.getName()); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtils.closeSession(session); } } /** * 大批量的数据添加,如果放大量的缓存会溢出,定期清理一下缓存 */ public void testCache7(){ Session session=null; try { session=HibernateUtils.getSession(); session.beginTransaction(); for (int i = 0; i <100; i++) { Student student =new Student(); student.setName("张三" +i); session.save(student); if (i%20==0) { //执行sql语句,相当于把这些缓存全部保存到数据库中了 session.flush(); //清楚缓存的内容 session.clear(); } } session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally{ HibernateUtils.closeSession(session); } } }
下面是对上面代码的提取总结:
因为Session的生命周期往往很短,存在于Session内部的第一集最快缓存的生命周期也是很短的,所以一级缓存的命中率很低的。其对系统性能的改善也是很有限的。当然,这个session内部缓存的主要作用是保持session内部数据状态同步,并非是hibernate为了大幅提高系统性能所提供的。
为了提高使用hibernate的性能,除了常规的一些需要注意的方法,如:用延迟加载、迫切外链接、查询过滤等以外,还需要配置hibernate的二级缓存。其对系统性能的改善往往立竿见影。下篇我就来介绍一下二级缓存。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/lvshihua/article/details/47177209