hibernate 缓存

来源:互联网 发布:守望先锋性能数据fps 编辑:程序博客网 时间:2024/06/07 09:20

Hibernate三种状态   

①.对于刚创建的一个对象,如果session中和数据库中都不存在该对象,那么该对象就是临时对象(Transient)
 
  ②.临时对象调用save方法或者游离对象调用update方法可以使该对象变成持久化对象,如果对象是持久化对象时,那么对该对象的任何修改,都会在提交事务时才会与之进行比较,如果不同,则发送一条update语句,否则就不会发送语句
 
 ③游离对象就是,数据库存在该对象,但是该对象又没有被session所托管


缓存:


一级缓存属于事务范围,由hibernate自己管理,程序员无需干预
二级缓存属于进程范围和集群范围,可以进行配置和动态卸载加载

二级缓存:

evict(Class arg0, Serializable arg1)将某个类的指定ID的持久化对象从二级缓存中清除,释放对象所占用的资源。
sessionFactory.evict(Customer.class, new Integer(1));
evict(Class arg0)  将指定类的所有持久化对象从二级缓存中清除,释放其占用的内存资源。
sessionFactory.evict(Customer.class);
evictCollection(String arg0)  将指定类的所有持久化对象的指定集合从二级缓存中清除,释放其占用的内存资源。

hibernatenate 延迟加载  lazy="false" 关闭
二级缓存配置:

创建缓存文件ehcache.xml
<!-- ehcache配置(ehcache.xml)
<?xml version="1.0" encoding="UTF-8"?><ehcache> <!--如果缓存中的对象存储超过指定的缓存数量的对象存储的磁盘地址--><diskStore path="E:/ehcache"/>  <!-- 默认cache:如果没有对应的特定区域的缓存,就使用默认缓存 --><defaultCache maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="300"timeToLiveSeconds="600"overflowToDisk="false"/> <!-- 指定区域cache:通过name指定,name对应到Hibernate中的区域名即可--><cache name="com.ittx.hibernate001.model.Student"eternal="false"maxElementsInMemory="100"timeToIdleSeconds="1200"timeToLiveSeconds="1200"overflowToDisk="false"></cache>  </ehcache>

cache参数详解:

● name:指定区域名
● maxElementsInMemory :缓存在内存中的最大数目
● maxElementsOnDisk:缓存在磁盘上的最大数目
● eternal :设置是否永远不过期
● overflowToDisk : 硬盘溢出数目
● timeToIdleSeconds :对象处于空闲状态的最多秒数后销毁
● timeToLiveSeconds :对象处于缓存状态的最多秒数后销毁
● memoryStoreEvictionPolicy:缓存算法,有LRU(默认)、LFU、LFU 

关于缓存算法,常见有三种:
● LRU:(Least Rencently Used)新来的对象替换掉使用时间算最近很少使用的对象
● LFU:(Least Frequently Used)替换掉按命中率高低算比较低的对象
● LFU:(First In First Out)把最早进入二级缓存的对象替换掉  -->

hibernate.cfg.xml中添加如下配置:

<!-- 高速缓存提供程序 --><property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property><!-- 设置二级缓存插件EHCache的Provider类 --><property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property><!-- enable second level cache and query cache --><property name="hibernate.cache.use_second_level_cache">true</property><!-- 启动"查询缓存"如果想缓存使用findall()、list()、Iterator()、createCriteria()、createQuery()等方法获得的数据结果集,必须配置此项 --><property name="hibernate.cache.use_query_cache">true</property><!-- 指定缓存配置文件位置 --><property name="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</property><!-- 强制Hibernate以更人性化的格式将数据存入二级缓存 --><property name="hibernate.cache.use_structured_entries">true</property><!-- Hibernate将收集有助于性能调节的统计数据 --><property name="hibernate.generate_statistics">true</property>

映射文件中添加:

在class标签下添加如下配置:
<cache usage="read-write"/>





状态实例:

实例
/** * 在调用了save方法后,此时user已经是持久化对象了,被保存在了session缓存当中,    * 这时user又重新修改了属性值,那么在提交事务时,此时hibernate对象就会拿当前这个user对象    * 和保存在session缓存中的user对象进行比较,如果两个对象相同,则不会发送update语句,    * 否则,如果两个对象不同,则会发出update语句。    update user set name=?, age=?, sex=?, * headuri=? where id=? *  */@Testpublic void testOne() {User user = new User("张三", 23, 0); // 临时状态session.save(user); // user 持久状态user.setName("李四");// session.update(user);}/** * 我们来看看此时会发出多少sql语句呢? 同样记住一点:当session调用load、get方法时,此时如果数据库中有该对象,    * 则该对象也变成了一个持久化对象,被session所托管。因此,这个时候如果对对象进行操作,    * 在提交事务时同样会去与session中的持久化对象进行比较,因此这里会发送两条sql语句    */@Testpublic void testTwo() {User user = session.get(User.class, 13); // 持久化状态(数据库中有,session缓存也有)user.setAge(18);user.setName("王二");}/** *    * 当我们load出user对象时,此时user是持久化的对象,在session缓存中存在该对象,此时我们在对user进行修改后,    * * 然后调用session.clear()方法,这个时候就会将session的缓存对象清空,那么session中就没有了user这个对象,    * * 这个时候在提交事务的时候,发现session中已经没有该对象了,所以就不会进行任何操作,因此这里只会发送一条select语句    */@Testpublic void testThire() {User user = session.get(User.class, 13); // 持久化状态(数据库中有,session缓存也有)user.setAge(28);user.setName("李四");session.evict(user); // 清除session缓存中指定对象// session.clear(); //清除session缓存}/** *    * 我们看到,当调用了user.setId(13)时,此时user是一个离线的对象,因为数据库中存在id=13的这个对象,    * * 但是该对象又没有被session所托管,所以这个对象就是游离的对象,要使游离对象变成一个持久化的对象,    * * 应该调用什么方法呢?我们知道调用save方法,可以将一个对象变成一个持久化对象,但是,当save一执行的时候,    * * 此时hibernate会根据id的生成策略往数据库中再插入一条数据,所以如果调用save方法,此时数据库会发送一条插入的语句:    *    * * 所以对于游离对象,如果要使其变成持久化对象的话,我们不能使用save方法,而应该使用update方法    */@Testpublic void testFour() {User user = new User("王二", 23); // user 临时状态对象user.setId(14); // user 游离状态对象 (数据库存在,session缓存中不存)session.update(user); // user对象 持久化状态对象user.setName("大丽");}@Testpublic void testFive() {User user = new User("小丽", 18); // user 临时状态对象user.setId(13); // user 游离状态对象 (数据库存在,session缓存中不存)session.delete(user); // user对象 临时状态对象user.setName("大丽");}




原创粉丝点击