一级缓存与session周期一致,二级缓存与sessionFactory一致。
session一级缓存
1、一级缓存很短,和session的生命周期一致,随着session的关闭而消失
*load/get/iterate(查询实体对象)可以使用缓存数据
2、一级缓存它缓存的是实体对象
3、如果管理缓存,如session.clear()/session.evict()
4、如何避免一次性大批量实体数据插入内存溢出的问题?
*先执行flush,在用clear清除缓存
班级与学生类,一对多示例演示
package com.bjsxt.hibernate;
import java.io.Serializable;
import org.hibernate.Session;
import junit.framework.TestCase;
public class CacheLevel1Test extends TestCase {
/**
* 发出两次load查询,只发出一条语句
*
*/
public void testCache1() {
Session session = null;
try {
session = HibernateUtils.getSession();
Student student = (Student)session.load(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
//因为有一级缓存,load方法使用一级缓存,所以本次查询不再发出sql
student = (Student)session.load(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 发出两次get查询
*
*/
public void testCache2() {
Session session = null;
try {
session = HibernateUtils.getSession();
Student student = (Student)session.get(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
//因为有一级缓存,get方法使用一级缓存,所以本次查询不再发出sql
student = (Student)session.get(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 发出两次iterate查询实体对象
*
*/
public void testCache3() {
Session session = null;
try {
session = HibernateUtils.getSession();
Student student = (Student)session.createQuery("from Student where id=1").iterate().next();
System.out.println("学生姓名:" + student.getName());
//因为有一级缓存,iterate方法使用一级缓存,发出查询id的sql,不再发出查询实体对象的sql,一级缓存它缓存的是实体对象
student = (Student)session.createQuery("from Student where id=1").iterate().next();
System.out.println("学生姓名:" + student.getName());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 发出两次iterate查询普通属性
*
*/
public void testCache4() {
Session session = null;
try {
session = HibernateUtils.getSession();
String name = (String)session.createQuery("select name from Student where id=1").iterate().next();
System.out.println("学生姓名:" + name);
//Iterate查询普通结果集,一级缓存不会缓存,它也不会发出查询id的sql
name = (String)session.createQuery("select name from Student where id=1").iterate().next();
System.out.println("学生姓名:" + name);
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 打开两次session,调用load测试
*
*/
public void testCache5() {
Session session = null;
try {
session = HibernateUtils.getSession();
Student student = (Student)session.load(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
//打开第二个session
try {
session = HibernateUtils.getSession();
//会发出sql,session间是不能共享一级缓存数据的
//因为它会伴随session的生命周期存在和消亡
Student student = (Student)session.load(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 先执行save,再执行load进行测试
*
*/
public void testCache6() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Student student = new Student();
student.setName("张三");
Serializable id = session.save(student);
//因为save会将实体对象的数据缓存到session中
//所以再次查询相同数据,不会发出sql
Student newStudent = (Student)session.load(Student.class, id);
System.out.println("学生姓名:" + newStudent.getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 执行session.clear()或session.evict()方法后,再调用load
*/
public void testCache7() {
Session session = null;
try {
session = HibernateUtils.getSession();
Student student = (Student)session.load(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
//管理session缓存(一级缓存机制无法取消的,但可以管理缓存,如:clear,evict方法)
session.evict(student);
//session.clear();
//发出sql,因为缓存中的student实体类,已经被逐出
student = (Student)session.load(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}
/**
* 向数据库中插入10000学生数据
*
*/
public void testCache8() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
for (int i = 0; i < 10000; i++) {
Student student = new Student();
student.setName("Student_" + i);
session.save(student);
//每100条数据就强制session将数据持久化
//同时清空缓存,以避免在大量的数据下,造成内存溢出
if ( i % 100 == 0) {
session.flush();
session.clear();
}
}
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}