先看一个例子:
假设我的工程中有个与user类(实体类,与数据库映射),userDao(继承自 AbstractHibernateDao),userService。在userService中运行这段代码:
void saveUser(user us){
//设us中name属性为a
userDao.save(us);
us.setName("b");
}
运行后数据库表中user表的name属性变为了”b”,新手的我觉得很奇怪,明明我修改us后没有对它进行保存,为什么会自动保存在数据库表中?
后来上网查找,发现了个hibernate缓存机制这个东西。
先介绍一下hibernate缓存机制,摘自
一、why(为什么要用Hibernate缓存?)
Hibernate是一个持久层框架,经常访问物理数据库。
为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。
缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。
看到介绍,就基本明白了刚刚问题发生的原因,我在save(us)时hibernate并没有即时叫数据提交至数据库中,而是放入缓存,而us.setName(“b”)运行修改了缓存中的us对象,而等事务结束后,再将缓存的数据存储至数据库中,如果想即时存储,应调用session.flush()方法,把缓存的数据存入数据库中。
摘抄点源博客的东西:
缓存有Session缓存和SessionFactory缓存,Session缓存是默认加载使用的,SessionFactory是一个可配置的插件。
缓存的使用:
1. 一级缓存的管理:
evit(Object obj) 将指定的持久化对象从一级缓存中清除,释放对象所占用的内存资源,指定对象从持久化状态变为脱管状态,从而成为游离对象。
clear() 将一级缓存中的所有持久化对象清除,释放其占用的内存资源。
contains(Object obj) 判断指定的对象是否存在于一级缓存中。
flush() 刷新一级缓存区的内容,使之与数据库数据保持同步。
2.一级缓存应用: save()。当session对象调用save()方法保存一个对象后,该对象会被放入到session的缓存中。 get()和load()。当session对象调用get()或load()方法从数据库取出一个对象后,该对象也会被放入到session的缓存中。 使用HQL和QBC等从数据库中查询数据。
3.二级缓存的管理:
evict(Class arg0, Serializable arg1)将某个类的指定ID的持久化对象从二级缓存中清除,释放对象所占用的资源。
sessionFactory.evict(Customer.class, new Integer(1));
evict(Class arg0) 将指定类的所有持久化对象从二级缓存中清除,释放其占用的内存资源。
sessionFactory.evict(Customer.class);
evictCollection(String arg0) 将指定类的所有持久化对象的指定集合从二级缓存中清除,释放其占用的内存资源。
sessionFactory.evictCollection(“Customer.orders”);
4.二级缓存的配置
常用的二级缓存插件
EHCache org.hibernate.cache.EhCacheProvider
OSCache org.hibernate.cache.OSCacheProvider
SwarmCahe org.hibernate.cache.SwarmCacheProvider
JBossCache org.hibernate.cache.TreeCacheProvider
本文介绍了Hibernate缓存机制,包括一级缓存和二级缓存的管理、应用以及配置。通过一个例子展示了未保存的实体对象如何因缓存机制在事务结束后自动保存到数据库。缓存的使用能降低对物理数据库的访问频次,提高性能。一级缓存由Session管理,而二级缓存可通过各种插件如EHCache、OSCache等进行配置。
21万+

被折叠的 条评论
为什么被折叠?



