详解Java的Hibernate框架中的缓存与二级缓存
缓存 今天我们就来讲一下hibernate中实体状态和hibernate缓存。 Transaction tx = session.beginTransaction(); User user = new User(); user.setName("shun"); //这里的user还未保存到数据库,数据库表中并没有与之对应的记录,它为transient状态 session.save(user); tx.commit(); //提交之后user变为persistent状态 session.close(); //由于session关闭,此时的user为detached状态,它的所有修改都不会反映到数据库中。 Session session2 = sessionFactory.openSession(); tx = session2.beginTransaction(); user.setName("shun123"); session2.saveOrUpdate(user); tx.commit(); //当我们调用了saveOrUpdate之后,user重新变为persistent状态,它的所有修改都会反映到数据库中。 session2.close(); 我们看到代码,首先我们定义了一个对象user,在未保存之前,它就是transient状态,在数据库中并没有与它相应的记录。而当我们进行保存并提交修改后,user成为persistent状态,在数据库中有相应的一条记录。而当我们把session关闭后,user就变成了detached状态了,它的更改并不会反映到数据库中,除非我们手动调用saveOrUpdate等相应的更新和添加方法。而当我们直接想让它从persistent到transient状态,怎么办呢?直接删除就可以了,删除后对象就在数据库中没有对应的记录,也就成transient状态了。 public static void main(String[] args) { Configuration cfg = new Configuration().configure(); SessionFactory sessionFactory = cfg.buildSessionFactory(); Session session = sessionFactory.openSession(); User user = (User)session.load(User.class,new Long(29)); System.out.println(user.getName()); User user2 = (User)session.load(User.class,new Long(29)); System.out.println(user2.getName()); session.close(); } 看结果: Hibernate: select user0_.USER_ID as USER1_0_0_,user0_.USER_NAME as USER2_0_0_,user0_.age as age0_0_ from USER user0_ where user0_.USER_ID=? shun123123 shun123123 例子中我们用了两次load,但结果中只有一句SQL语句,这表明它只查询了一次。 User user = (User)session.load(User.class,new Long(29)); System.out.println(user.getName()); session.evict(user);//把user从缓存中删掉 User user2 = (User)session.load(User.class,new Long(29)); System.out.println(user2.getName()); session.close(); 看到结果: Hibernate: select user0_.USER_ID as USER1_0_0_,user0_.age as age0_0_ from USER user0_ where user0_.USER_ID=? shun123123 Hibernate: select user0_.USER_ID as USER1_0_0_,user0_.age as age0_0_ from USER user0_ where user0_.USER_ID=? shun123123 自己我们把user从缓存中删除后,第二次的查询也直接从数据库中取出。 二级缓存小谈 public class User implements Serializable{ public Long id; private String name; private int age; } 映射文件就省略啦,大家应该都会写的。 <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.use_query_cache">true</property> 我们看到provider_class中我们指定了ehcache这个提供类,所以我们也需要ehcache.xml放在classpath中: <?xml version="1.0" encoding="UTF-8"?> <ehcache> <diskStore path="java.io.path"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> </ehcache> 接下来,我们直接看一下测试方法: public static void main(String[] args) { Configuration cfg = new Configuration().configure(); SessionFactory sessionFactory = cfg.buildSessionFactory(); Session session = sessionFactory.openSession(); Query query = session.createQuery("from User user where name = 'shun123'"); Iterator iter = query.iterate(); while(iter.hasNext()) { System.out.println(((User)iter.next()).getName()); } session.close(); Session session2 = sessionFactory.openSession(); Query query2 = session2.createQuery("from User user where name='shun123'"); Iterator iter2 = query2.iterate(); while(iter2.hasNext()) { System.out.println(((User)iter2.next()).getName()); } session2.close(); } 运行后可以看到: Hibernate: select user0_.USER_ID as col_0_0_ from USER user0_ where user0_.USER_NAME='shun123' Hibernate: select user0_.USER_ID as USER1_0_0_,user0_.age as age0_0_ from USER user0_ where user0_.USER_ID=? shun123 Hibernate: select user0_.USER_ID as col_0_0_ from USER user0_ where user0_.USER_NAME='shun123' shun123 我们可以看到它只执行了一句搜索,而在第二次查询时并没有取出ID进行搜索,这主要归功于二级缓存。 <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.use_query_cache">true</property> 如果我们需要使用二级缓存,首先需要配置: <property name="hibernate.cache.use_second_level_cache">true</property> 进行开户二级缓存,然后通过: <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> 指定二级缓存的提供类,一般情况下我们都用ehcache,其他我的暂时没用到,也不太清楚,所以暂时不讲了。 <property name="hibernate.cache.use_query_cache">true</property> 这个配置指明了我们在查询时需要利用缓存,如果我们需要用到这个要事先调用query.setCacheable(true)这个方法来进行启用。 public static void main(String[] args) { Configuration cfg = new Configuration().configure(); SessionFactory sessionFactory = cfg.buildSessionFactory(); Session session = sessionFactory.openSession(); Query query = session.createQuery("from User user where name = 'shun123'"); List list = query.list(); for (int i = 0; i < list.size(); i++){ System.out.println(((User)list.get(i)).getName()); } session.close(); Session session2 = sessionFactory.openSession(); Query query2 = session2.createQuery("from User user where name='shun123'"); List list2 = query2.list(); for (int i = 0; i < list2.size(); i++){ System.out.println(((User)list.get(i)).getName()); } session2.close(); } (编辑:台州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |