hibernate缓存的使用
2012-01-03 20:29:03| 分类: JAVA 技术支持 | 标签:java hibernate ssh 缓冲 |字号大中小 订阅
缓存的使用
我们先来模拟一个缓存的机制
以查询学生为示例:
public class Test {
public static void main(String[] args) throws Exception {
MyClassDao myClassDao = new MyClassDao();
StudentDao studentDao = new StudentDao();
Student student = studentDao.findById("4028810027d8be080127d8be0d790002");
System.out.println(student.getName());
Student student2 = studentDao.findById("4028810027d8be080127d8be0d790002");
System.out.println(student2.getName());
}
}
可以看到控制台输出:
很明显的看到执行了两条SQL语句,感觉有点浪费资源,如果我们把第一次查询的结果保存起来,当第二次查询的时候,先看保存了没有,如果有,直接用,如果没有,则再查询数据库.这样就更好一些.
修改StudentDao层,给Dao类增加一个模拟的缓存集合
public class StudentDao {
public static Map<String, Student> cache = new HashMap<String, Student>();
public void create(Student student) throws Exception {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
session.save(student);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}
public void delete(Student student) throws Exception {
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
session.delete(student);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
}
public Student findById(Serializable id) throws Exception {
Session session = null;
Transaction transaction = null;
Student student = null;
String key = Student.class.getName() + id;
student = cache.get(key);
if (student != null) {
return student;
}
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
student = (Student) session.get(Student.class, id);
cache.put(key, student);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
return student;
}
}
再一次执行Test的main方法,可以看到结果如下:
只执行了一次查询,这就是缓存的一个作用,但是缓存机制远远不会这么简单,想一下,如果在两次查询之间,对象更新了怎么办,这就涉及到缓存的更新.我们暂时只需要了解一下缓存的机制与简单的实现.因为这一块已经有现成的包和类直接用,不需要我们再从头开发.
缓存的作用主要是用来提高性能,可以简单的理解成一个Map,使用缓存涉及到三个操作:
把数据放入缓存
从缓存中获取数据
删除缓存中无效数据
一级缓存: Session级共享,此缓存只能在session关闭之前使用.
save, update, saveOrUpdate, get, list, iterate, lock这些方法都会将对象放在一级缓存中, 一级缓存不能控制缓存的数量, 所以要注意大批量操作数据时可能造成内在溢出, 可以用evict, clear方法清除缓存中的内容.后面讲到Hibernate批量增加数据时再演示.
看下面的代码:
public Student findById(Serializable id) throws Exception {
Session session = null;
Transaction transaction = null;
Student student = null;
try {
session = HibernateUtil.getSession();
transaction = session.getTransaction();
transaction.begin();
student = (Student) session.get(Student.class, id);
System.out.println(student.getName());
Student student1 = (Student) session.get(Student.class, id);
System.out.println(student1.getName());
transaction.commit();
} catch (Exception e) {
transaction.rollback();
throw e;
}
return student;
}
可以看到上面的代码中,只查询了一次数据库,但是缓存的作用域太小,没有太大的作用.
二级缓存: SessionFactory级共享
实现为可插拔,通过修改两个开关来改变.
告诉Hibernate,我现在要使用缓存机制:
<property name="hibernate.cache.use_second_level_cache">true</property>
配置二级缓存的提供者,也就是具体厂商提供的实现类<property name="cache.provider_class">
缓存的配置,可以在Hibernate源码包下查找hibernate.properties这个文件,找到Second-level Cache这一块,可以看到所有的配置项