true5、 指定哪些实体类使用二级缓存。
方法一:在对应实体的.hbm.xml文件中设置,这样如果我们想要知道二百个映射文件哪些使用了二级缓存,就要查看二百个文件,所以我们可以把对实体加入二级缓存的策略放到hibernate.cfg.xml进行配置。也就是方法二。
方法二:处于好管理的目的我们把哪个实体使用二级缓存的配置放到hibernate.cfg.xml文件中。例如执行把student实体加入二级缓存策略。
指定Student使用二级缓存
注意:缓存策略通常采用read-only和read-write 缓存原则;通常是读大于写的数据进行缓存。
开启二级缓存在两个session中使用两次load()进行查询
代码如下所示。
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
/**
* 开启二级缓存 *
* 在两个session中发load查询 */
public voidtestCache1() { Sessionsession = null; try {
session = HibernateUtils.getSession(); session.beginTransaction();
Studentstudent = (Student)session.load(Student.class, 1); System.out.println(\"student.name=\" +student.getName()); session.getTransaction().commit(); }catch(Exceptione) {
1 / 7
15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37.
打印结果如下图所示。 e.printStackTrace();
session.getTransaction().rollback(); }finally {
HibernateUtils.closeSession(session); } try {
session = HibernateUtils.getSession(); session.beginTransaction();
Studentstudent = (Student)session.load(Student.class, 1);
//不会发出查询语句,因为配置二级缓存,session可以共享二级缓存中的数据 //二级缓存是进程级的缓存
System.out.println(\"student.name=\" +student.getName()); session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace();
session.getTransaction().rollback(); }finally {
HibernateUtils.closeSession(session); } }
由此可知,虽然我们使用的是两个session,但第二次查询的时候没有再向数据库发出查询语句。也就是第一次查询的时候放入session的同时也放入SessionFactory缓存中一份,而第二个session再查询的时候,就直接从二级缓存中取出就可以了。
开启二级缓存,在两个session中发出load查询,采用SessionFactory管理二级缓存
代码如下所示。
1. 2. 3. 4. 5.
/**
* 开启二级缓存 *
* 在两个session中发load查询,采用SessionFactory管理二级缓存 */
2 / 7
6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39.
显示结果如下所示。
public voidtestCache3() { Sessionsession = null; try {
session= HibernateUtils.getSession(); session.beginTransaction();
Studentstudent = (Student)session.load(Student.class, 1); System.out.println(\"student.name=\" +student.getName()); session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace();
session.getTransaction().rollback(); }finally {
HibernateUtils.closeSession(session); }
//管理二级缓存 (evict清除的意思)
//HibernateUtils.getSessionFactory().evict(Student.class); HibernateUtils.getSessionFactory().evict(Student.class, 1); try {
session= HibernateUtils.getSession(); session.beginTransaction();
Studentstudent = (Student)session.load(Student.class, 1);
//会发出查询语句,因为二级缓存中的数据被清除了
System.out.println(\"student.name=\" +student.getName()); session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace();
session.getTransaction().rollback(); }finally {
HibernateUtils.closeSession(session); } }
3 / 7
根据显示结果可知,在两个session中发出load查询,第一次放入session缓存同时放入了二级缓存sessionFactory中。在第二个session中,首先使用SessionFactory对二级缓存管理,使用evict()方法清除二级缓存,所以第二个session采用load查询时,需要重新向数据库发送sql命令。
一级缓存和二级缓存交互
代码如下所示。
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32.
public voidtestCache4() { Sessionsession = null; try {
session= HibernateUtils.getSession(); session.beginTransaction();
//禁止将一级缓存中的数据放到二级缓存中。缓存模式设置为忽略。 session.setCacheMode(CacheMode.IGNORE);
Studentstudent =(Student)session.load(Student.class, 1); System.out.println(\"student.name=\" + student.getName()); session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace();
session.getTransaction().rollback(); }finally {
HibernateUtils.closeSession(session); } try {
session= HibernateUtils.getSession(); session.beginTransaction();
Studentstudent = (Student)session.load(Student.class, 1);
//会发出查询语句,因为禁止了一级缓存和二级缓存的交互,一级缓存没有放到二级缓存中。 System.out.println(\"student.name=\" +student.getName()); session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace();
session.getTransaction().rollback(); }finally {
HibernateUtils.closeSession(session); } }
4 / 7
显示结果如下所示。
从上图可以看出,首先我们开启session的事务,然后设置了当写入session缓存中的同时不写入二级缓存,session.setCacheMode(CacheMode.IGNORE),这样第二个session再查询的时候就不能从二级缓存中找到相应的内容,仍需向数据库发出sql请求。
大批量数据的添加。
当添加或更新大批量数据的时候,为了防止缓存中数据量过大,我们可以设置删除session一级缓存,如果此时开启二级缓存,那么也会同样再二级缓存中存放一份,这样的话很可能会导致缓存的溢出,所以对于大数据来说,如果放入了一级缓存中,就应该禁止再放入二级缓存中。
代码如下所示。
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.
/**
* 大批量的数据添加 */
public voidtestCache5() { Sessionsession = null; try {
session= HibernateUtils.getSession(); session.beginTransaction();
//禁止一级缓存和二级缓存交互
session.setCacheMode(CacheMode.IGNORE); for (int i=0;i<100; i++) {
Studentstudent = new Student(); student.setName(\"张三\" +i);
//一级缓存放一份,二级缓存也放一份。 session.save(student); //每20条更新一次 if (i %20 == 0) { session.flush(); //清除缓存的内容
//只清除了一级缓存中的内容,没有清除一级缓存中的内容。如果数据量过大,一样溢出。 //大于大数据量来说,如果配置了一级缓存的话,就应该禁止再放入二级缓存中。 session.clear();
5 / 7
24. 25. 26. 27. 28. 29. 30. 31. 32. 33.
控制台打印sql如下图所示。 } }
session.getTransaction().commit(); }catch(Exceptione) { e.printStackTrace();
session.getTransaction().rollback(); }finally {
HibernateUtils.closeSession(session); } }
Hibernate二级缓存总结
从上可知,二级缓存时比一级缓存作用域更大,是在整个应用程序中。一级缓存是不能被卸载的,是必需的,不允许也无法卸载,它是事务范围的缓存。而二级缓存是可配置的,可卸载的,SessionFactory生命周期和应用程序整个过程对应,就有可能出现并发问题。
什么样的数据适合放到二级缓存中? 1、 很少被修改的数据
2、 不是很重要的,并允许出现偶尔的并发数据 3、 不会被并发的数据 4、 常量数据
什么样的数据适不合放到二级缓存中? 1、 经常被修改的数据。
6 / 7
2、 绝对不允许并发的数据。 3、 与其他应用共享的数据。
本文作者:lovesummerforever
7 / 7