Hibernate 缓存_一级缓存
时间:2010-10-22 来源:juxiangwu
1、Hibernate的一级缓存
在Hibernate框架内部应用缓存提高应用系统的运行性能,Hibernate中的缓存分为为一级和二级缓存。
Hibernate的一级缓存是内置缓存,不能通过程序代码或者配置人为取消取消,并且一级缓存通过Session对象实现缓存,所以也被为“Session”缓存。一级缓存是事务级别的缓存,事务结束缓存中的所有数据失效。使用一级缓存可以在一个事务中减少查询和更新数据表的操作。如在一个事务中即使多次地修改一个持久对象,但在提交事务之时,Hibernate只会执行一个update子句更新数据库的数据,更新的数据包括事务提交之前所有的修改内容。
2、一级缓存的实现原理
在底层实现上,可以把一级缓存想象为Session对象维护一个Map对象,其中保存当前Session对象使用的数据。通过Session对象读取数据时,该对象会首先依据要加载对象的类型和标识符属性查找这个Map对象中是否已经加载过这个持久化对象。如果找到,则直接返回这个对象;否则从数据库中查询,加载数据后同时会把这个持久化对象保存在Map对象中。
3、管理一级缓存
管理一级缓存包括以下几种方法:
(1)、使用evict()方法从缓存中移除对象
不能取消一级缓存的使用,但是可以使用Session的evict()方法从一级缓存中移除缓存的持久对象,同时该对象的状态会从持久化状态转换为托管状态。如:
public void testRemoveL1Cache(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Product p = (Product)session.get(Product.class, 1);
//移除一级缓存中的Product对象
session.evict(p);
Product p2 = (Product)session.get(Product.class, 1);
System.out.println(p==p2);
tx.commit();
session.close();
}
程序的执行结果如下:
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
false
说明一级缓存中的对象被移除后,Hibernate只能从数据库中加载,同时加载后的对象与原来的对不再是同一个对象。
(2)、使用clear()方法从缓存中清除所有对象。
用法如下:
public void testRemoveAllL1Cache(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Product p1 = (Product)session.get(Product.class, 1);
Product p2 = (Product)session.get(Product.class, 2);
//清除所有对象
session.clear();
Product p3 = (Product)session.get(Product.class, 1);
Product p4 = (Product)session.get(Product.class, 2);
System.out.println(p1==p3);
System.out.println(p2==p4);
tx.commit();
session.close();
}
程序执行结果如下:
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
false
false
(3)、使用Session对象的contains()、flush()和setReadOly()方法
Session对象的contains()方法判断指定的对象是否缓存在一级缓存中,flush()方法刷新(同步)一级缓存中的数据,使其与数据库中的数据保存一致,setReadOnly()方法设置某个持久化对象为只读对象,而只读对象不执行脏数据检查。
在Hibernate框架内部应用缓存提高应用系统的运行性能,Hibernate中的缓存分为为一级和二级缓存。
Hibernate的一级缓存是内置缓存,不能通过程序代码或者配置人为取消取消,并且一级缓存通过Session对象实现缓存,所以也被为“Session”缓存。一级缓存是事务级别的缓存,事务结束缓存中的所有数据失效。使用一级缓存可以在一个事务中减少查询和更新数据表的操作。如在一个事务中即使多次地修改一个持久对象,但在提交事务之时,Hibernate只会执行一个update子句更新数据库的数据,更新的数据包括事务提交之前所有的修改内容。
2、一级缓存的实现原理
在底层实现上,可以把一级缓存想象为Session对象维护一个Map对象,其中保存当前Session对象使用的数据。通过Session对象读取数据时,该对象会首先依据要加载对象的类型和标识符属性查找这个Map对象中是否已经加载过这个持久化对象。如果找到,则直接返回这个对象;否则从数据库中查询,加载数据后同时会把这个持久化对象保存在Map对象中。
3、管理一级缓存
管理一级缓存包括以下几种方法:
(1)、使用evict()方法从缓存中移除对象
不能取消一级缓存的使用,但是可以使用Session的evict()方法从一级缓存中移除缓存的持久对象,同时该对象的状态会从持久化状态转换为托管状态。如:
public void testRemoveL1Cache(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Product p = (Product)session.get(Product.class, 1);
//移除一级缓存中的Product对象
session.evict(p);
Product p2 = (Product)session.get(Product.class, 1);
System.out.println(p==p2);
tx.commit();
session.close();
}
程序的执行结果如下:
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
false
说明一级缓存中的对象被移除后,Hibernate只能从数据库中加载,同时加载后的对象与原来的对不再是同一个对象。
(2)、使用clear()方法从缓存中清除所有对象。
用法如下:
public void testRemoveAllL1Cache(){
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Product p1 = (Product)session.get(Product.class, 1);
Product p2 = (Product)session.get(Product.class, 2);
//清除所有对象
session.clear();
Product p3 = (Product)session.get(Product.class, 1);
Product p4 = (Product)session.get(Product.class, 2);
System.out.println(p1==p3);
System.out.println(p2==p4);
tx.commit();
session.close();
}
程序执行结果如下:
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
Hibernate: select product0_.id as id3_0_, product0_.name as name3_0_, product0_.price as price3_0_, product0_.description as descript4_3_0_ from tb_product product0_ where product0_.id=?
false
false
(3)、使用Session对象的contains()、flush()和setReadOly()方法
Session对象的contains()方法判断指定的对象是否缓存在一级缓存中,flush()方法刷新(同步)一级缓存中的数据,使其与数据库中的数据保存一致,setReadOnly()方法设置某个持久化对象为只读对象,而只读对象不执行脏数据检查。
相关阅读 更多 +