Hibernate中没有自己去实现二级缓存,而是利用第三方的。简单叙述一下配置过程,也作为自己以后用到的时候配置的一个参考。
案例:
新闻实体类:
package com.liuyongqi.MavenHibernateDemo8.entity;
import java.io.Serializable;
/**
* 新闻实体类
* @author Administrator
* @data 2018年7月31日
* @time 上午10:05:13
*/
public class News implements Serializable{
/**
*
*/
private static final long serialVersionUID = -7170520651423556216L;
private Integer nid ;
private String ntitle ;
private String ncontext ;
private String ndate ;
public News() {
super();
// TODO Auto-generated constructor stub
}
public News(String ntitle, String ncontext, String ndate) {
super();
this.ntitle = ntitle;
this.ncontext = ncontext;
this.ndate = ndate;
}
public News(Integer nid, String ntitle, String ncontext, String ndate) {
super();
this.nid = nid;
this.ntitle = ntitle;
this.ncontext = ncontext;
this.ndate = ndate;
}
public Integer getNid() {
return nid;
}
public void setNid(Integer nid) {
this.nid = nid;
}
public String getNtitle() {
return ntitle;
}
public void setNtitle(String ntitle) {
this.ntitle = ntitle;
}
public String getNcontext() {
return ncontext;
}
public void setNcontext(String ncontext) {
this.ncontext = ncontext;
}
public String getNdate() {
return ndate;
}
public void setNdate(String ndate) {
this.ndate = ndate;
}
@Override
public String toString() {
return "News [nid=" + nid + ", ntitle=" + ntitle + ", ncontext=" + ncontext + ", ndate=" + ndate + "]";
}
}
1、我们需要加入额外的二级缓存包,例如EHcache,将其包导入。需要:ehcache-core-2.4.3.jar , hibernate-ehcache-4.2.4.Final.jar ,slf4j-api-1.6.1.jar 2、在hibernate.cfg.xml配置文件中配置我们二级缓存的一些属性(此处针对的是Hibernate4):
<!-- 启用二级缓存 -->
<property name="cache.use_second_level_cache">true</property>
<!-- 配置使用的二级缓存的产品 -->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
3、我们使用的是EHcache,所以我们需要创建一个ehcache.xml的配置文件,来配置我们的缓存信息,这个是EHcache要求的。该文件放到根目录下。
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!-- <diskStore path="java.io.tmpdir"/> -->
<diskStore path="E:/Apach/Hibernate-ehcache"/>
<transactionManagerLookup class="net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup"
properties="jndiName=java:/TransactionManager" propertySeparator=";"/>
<cacheManagerEventListenerFactory class="" properties=""/>
<!-- <diskStore path="E:/Apach/Hibernate-ehcache"/> -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
<cache name="com.liuyongqi.MavenHibernateDemo8.entity.News"
maxElementsInMemory="1000"
eternal="true"
timeToIdleSeconds="10"
timeToLiveSeconds="50"
overflowToDisk="true"
/>
</ehcache>
4、开启二级缓存。我们在这里使用的xml的配置方式,所以要在News.hbm.xml文件加一点配置信息:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2018-8-9 15:37:18 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.liuyongqi.MavenHibernateDemo8.entity.News" table="news" >
<!-- <cache usage="read-only"/> -->
<cache usage="read-write"/>
<id name="nid" type="java.lang.Integer">
<column name="nid" />
<generator class="native" />
</id>
<property name="ntitle" type="java.lang.String">
<column name="ntitle" />
</property>
<property name="ncontext" type="java.lang.String">
<column name="ncontext" />
</property>
<property name="ndate" type="java.lang.String">
<column name="ndate" />
</property>
</class>
</hibernate-mapping>
测试代码:
package test;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.query.Query;
import org.junit.Before;
import org.junit.Test;
import com.liuyongqi.MavenHibernateDemo8.entity.News;
/**
* Hibernate二级缓存
* @author Administrator
* @data 2018年8月9日
* @time 下午6:10:38
*/
public class TestCache2 {
private Session session;
private Transaction transaction;
private SessionFactory sessionFactory;
@Before
public void init() {
sessionFactory = new Configuration().configure().buildSessionFactory();
session= sessionFactory.openSession();
transaction= session.beginTransaction();
}
@Test
public void select1() {
News news1 = session.load(News.class, 2);
System.out.println("aaa");
System.out.println(news1);
transaction.commit();
session.close();
session= sessionFactory.openSession();
transaction= session.beginTransaction();
News news2 = session.load(News.class, 2);
System.out.println("bbb");
System.out.println(news2);
}
}
控制台结果:
aaa
Hibernate:
select
news0_.nid as nid1_0_0_,
news0_.ntitle as ntitle2_0_0_,
news0_.ncontext as ncontext3_0_0_,
news0_.ndate as ndate4_0_0_
from
news news0_
where
news0_.nid=?
News [nid=2, ntitle=不一样的人1, ncontext=杀杀杀, ndate=2018-05-19 17:46:46.0]
bbb
News [nid=2, ntitle=不一样的人1, ncontext=杀杀杀, ndate=2018-05-19 17:46:46.0]
我们可以发现控制台只发出了一条SQL语句。这是我们二级缓存的一个小Demo。
我们的二级缓存是sessionFactory级别的,所以当我们session关闭再打开之后,
我们再去查询对象的时候,此时Hibernate会先去二级缓存中查询是否有该对象。
同样,二级缓存缓存的是对象,如果我们查询的是对象的一些属性,则不会加入到缓存中。
我们通过二级缓存是可以解决之前提到的N+1问题。
今天的测试就到这里了,希望大家看完以后自己测试一下
如果大家想浏览我的下一篇文章,请留言
此文章属于原创,不准随意转载:https://blog.csdn.net/LYQ2332826438