Hibernate性能优化:一级缓存

一级缓存与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);
		}		
	}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值