hibernate 全面学习 【hibernate 缓存学习 】

hibernate 缓存分为一级缓存和二级缓存,及查询缓存

hinbernate 一级缓存

1、一级缓存很短,和session的生命周期一致,随着session的关闭而消失
*load/get/iterate(查询实体对象)可以使用缓存数据
2、一级缓存它缓存的是实体对象
3、如果管理缓存,如session.clear()/session.evict()
4、如何避免一次性大批量实体数据插入内存溢出的问题?
*先执行flush,在用clear清除缓存

hibernate 二级缓存

定义步骤:
1、打开缓存,在hibernate.cfg.xm中加入:
<property name="hibernate.cache.use_second_level_cache">true</property>

2、指定缓存策略提供商,在hibernate.cfg.xm中加入:
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

3、拷贝echcahe.xml到src下,可以针对不同的策略配置缓存

4、指定那些类使用缓存(两种方式)
* 在hibernate.cfg.xml
* 在映射文件中

二级缓存中存储的也是实体对象,他们都属于SessionFactory级别,
是全局的,伴随SessionFactory的生命周期存在和消亡

需要了解一级缓存和二级缓存的交互模式(CacheMode)


hibernate查询缓存

配置:
在hibernate.cfg.xml文件中加入:<property name="hibernate.cache.use_query_cache">true</property>

1、针对普通属性结果集的缓存
2、对是实体对象的结果集,只缓存id
3、使用查询缓存,需要打开查询缓存,并且在调用list方法之前需要显示的调用query.setCacheable(true);

[b]一级缓存[/b]


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);
}
}
}


[b]二级缓存测试[/b]

package com.bjsxt.hibernate;

import java.io.Serializable;

import org.hibernate.CacheMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import junit.framework.TestCase;

public class CacheLevel2Test extends TestCase {

/**
* 打开两次session,调用load测试
*
*/
public void testCache1() {
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
Student student = (Student)session.load(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}

/**
* 调用了次load,第一次调用完成后,清除sessionFactory中的二级缓存数据,
* 再开启一个session,调用load
*
*/
public void testCache2() {
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);
}

//管理二级缓存
SessionFactory factory = HibernateUtils.getSessionFactory();
factory.evict(Student.class);

//打开第二个session
try {
session = HibernateUtils.getSession();

//因为二级缓存已经被清空,所以本次查询将发出一条新的sql
Student student = (Student)session.load(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}

/**
* 调用了次load,第一次调用完成后,清除sessionFactory中的二级缓存数据,
* 再开启一个session,调用load
*
*/
public void testCache3() {
Session session = null;
try {
session = HibernateUtils.getSession();

//GET的CahceMode,使得session指会从sessionFactory中获取数据
//而不向其中添加数据
session.setCacheMode(CacheMode.GET);

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
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();
session.setCacheMode(CacheMode.PUT);
//不会读数据,所以发出sql
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
Student student = (Student)session.load(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}

}
}


[b]查询缓存[/b]

package com.bjsxt.hibernate;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

import org.hibernate.CacheMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import junit.framework.TestCase;

public class QueryCacheTest extends TestCase {

/**
* 执行两次query
*
*/
public void testCache1() {
Session session = null;
try {
session = HibernateUtils.getSession();
Query query = session.createQuery("select s.name from Student s");
query.setCacheable(true);

List names = query.list();
for (Iterator iter = names.iterator(); iter.hasNext();) {
String name = (String)iter.next();
System.out.println(name);
}
System.out.println("----------------------------------------------------");
//不再发出sql,因为启用了查询缓存
query = session.createQuery("select s.name from Student s");
query.setCacheable(true);
names = query.list();
for (Iterator iter = names.iterator(); iter.hasNext();) {
String name = (String)iter.next();
System.out.println(name);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}

/**
* 执行两次query,第二个query新open一个session
*
*/
public void testCache2() {
Session session = null;
try {
session = HibernateUtils.getSession();
Query query = session.createQuery("select s.name from Student s");
query.setCacheable(true);
List names = query.list();
for (Iterator iter = names.iterator(); iter.hasNext();) {
String name = (String)iter.next();
System.out.println(name);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}

try {
session = HibernateUtils.getSession();
System.out.println("----------------------------------------------------");
//不再发出sql,因为查询缓存的生命周期和session无关
Query query = session.createQuery("select s.name from Student s");
query.setCacheable(true);
List names = query.list();
for (Iterator iter = names.iterator(); iter.hasNext();) {
String name = (String)iter.next();
System.out.println(name);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}

/**
* 采用query.iterate测试
*
*/
public void testCache3() {
Session session = null;
try {
session = HibernateUtils.getSession();
Query query = session.createQuery("select s.name from Student s");
query.setCacheable(true);

Iterator iter = query.iterate();
while (iter.hasNext()) {
String name = (String)iter.next();
System.out.println(name);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}

try {
System.out.println("----------------------------------------------------------");
session = HibernateUtils.getSession();
Query query = session.createQuery("select s.name from Student s");
query.setCacheable(true);

//query.iterate()操作不会使用查询缓存
//!!!查询缓存只对query.list()操作有效!
Iterator iter = query.iterate();
while (iter.hasNext()) {
String name = (String)iter.next();
System.out.println(name);
}
}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}
}

/**
* 1、使用查询缓存
* 2、查询实体对象数据
* 3、把二级缓存关闭
*
*/
public void testCache4() {
Session session = null;
try {
session = HibernateUtils.getSession();
Query query = session.createQuery("select s from Student s");
query.setCacheable(true);
List students = query.list();
for (Iterator iter = students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}
System.out.println("-------------------------------------------------");
query = session.createQuery("select s from Student s");
query.setCacheable(true);
students = query.list();
for (Iterator iter = students.iterator(); iter.hasNext();) {
Student student = (Student)iter.next();
System.out.println(student.getName());
}

}catch(Exception e) {
e.printStackTrace();
}finally {
HibernateUtils.closeSession(session);
}

// try {
// System.out.println("-------------------------------------------------");
// session = HibernateUtils.getSession();
// //将会发出n条查询语句,因为二级缓存被关闭,而查询缓存中的数据只是实体对象的id
// //list操作会根据这些id依次到数据库中查找
// Query query = session.createQuery("select s from Student s");
// query.setCacheable(true);
// List students = query.list();
// for (Iterator iter = students.iterator(); iter.hasNext();) {
// Student student = (Student)iter.next();
// System.out.println(student.getName());
// }
// }catch(Exception e) {
// e.printStackTrace();
// }finally {
// HibernateUtils.closeSession(session);
// }

}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值