详解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();
}
(编辑:哈尔滨站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
