缓存由ORM框架提供以便用户可以获得更快速的访问速度,同时框架本身也减少了数据库查询操作。hibernate同样在两个层上提供了缓存的功能。
一级缓存:这是在session范围内默认使用的,了解更多可以读这篇文章。
二级缓存:这是在一级缓存之上的缓存,在session factory 范围内有效。
在这篇文章中,我将给出使用ehcache在hibernate配置二级缓存的例子。
这篇文章的结构:
二级缓存是如何工作的
关于ehcache
配置ehcache
配置实体对象
查询缓存
应用例子
源码下载
关于更多二级缓存是如何工作的,可以参考这篇文章。
net.sf.ehcache
ehcache
[2.0.0]
pom
true
net.sf.ehcache.hibernate.EhCacheRegionFactory
true
net.sf.ehcache.hibernate.EhCacheProvider
@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY,
region="department")
public class DepartmentEntity implements Serializable
{
//code
}
true
sessionFactory.getCurrentSession().createQuery("...").setCacheable(true).list();
/ehcache.xml
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/hibernatedemo
password
root
org.hibernate.dialect.MySQLDialect
true
create
org.hibernate.cache.EhCacheProvider
package hibernate.test.dto;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity (name = "dept")
@Table(name = "DEPARTMENT", uniqueConstraints = {
@UniqueConstraint(columnNames = "ID"),
@UniqueConstraint(columnNames = "NAME") })
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="department")
public class DepartmentEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID", unique = true, nullable = false)
private Integer id;
@Column(name = "NAME", unique = true, nullable = false, length = 100)
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package hibernate.test;
import java.io.File;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
public class HibernateUtil
{
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory()
{
try
{
// Create the SessionFactory from hibernate.cfg.xml
return new AnnotationConfiguration().configure(new File("hibernate.cgf.xml")).buildSessionFactory();
}
catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}
public class TestHibernateEhcache
{
public static void main(String[] args)
{
storeData();
try
{
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
//fetch the department entity from database first time
DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
//fetch the department entity again; Fetched from first level cache
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
//Let's close the session
session.getTransaction().commit();
session.close();
//Try to get department in new session
Session anotherSession = HibernateUtil.getSessionFactory().openSession();
anotherSession.beginTransaction();
//Here entity is already in second level cache so no database query will be hit
department = (DepartmentEntity) anotherSession.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
anotherSession.getTransaction().commit();
anotherSession.close();
}
finally
{
System.out.println(HibernateUtil.getSessionFactory().getStatistics().getEntityFetchCount()); //Prints 1
System.out.println(HibernateUtil.getSessionFactory().getStatistics().getSecondLevelCacheHitCount()); //Prints 1
HibernateUtil.shutdown();
}
}
private static void storeData()
{
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
DepartmentEntity department = new DepartmentEntity();
department.setName("Human Resource");
session.save(department);
session.getTransaction().commit();
}
}
Output:
Hibernate: insert into DEPARTMENT (NAME) values (?)
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
Human Resource
1
1