欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hibernate中get和load方法的区别

程序员文章站 2022-04-13 13:13:40
...

 

hibernate的准备及配置工作参见我的另一篇文章(该文章中介绍hibernate的搭建及简单配置) : http://ysj5125094.iteye.com/blog/1893871

下面的实现类是用JUnit测试的,如果想了解JUnit内容请参见我的另一篇文章: http://ysj5125094.iteye.com/blog/1897295

 

首先简单说一下get()和load()方法的区别,下面有具体的例子做验证。

get   : 不支持lazy ; 当要查询的记录不存在时,返回null。

load : 支持lazy ; 当要查询的记录不存在时,返回ObjectNotFoundException异常。

get和load都只能查询一条记录、并且get和load的查询条件必须是主键。

名词解释: lazy(延迟加载/懒加载),执行该方法时不与数据库打交道,也就是不执行查询操作,当用到该对象时,才执行查询操作。

 

下面是SessionTest.java类,主要看testGet和testLoad方法(本类是用JUnit实现测试的,读者可以用main测试,或者观看我的另外一篇文章,用JUnit实现):

package com.ysj;

import java.io.Serializable;
import java.util.Date;

import junit.framework.TestCase;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.ysj.utils.HibernateUtils;

public class SessionTest extends TestCase {
	
	/**
	 * 持久化对象生命周期的过程演示
	 */
	public void testSave(){
		Session session = null ;
		Transaction tran = null ;
		User user = null ;
		try{
			session = HibernateUtils.getSession() ;
			tran = session.beginTransaction() ;
			/**
			 * Transient(瞬态) :
			 * 1、在数据库中没有与之匹配的数据;
			 * 2、没有纳入session的管理;
			 * 3、如果在瞬态session 调用了 save()等方法就变为了持久态;
			 */  
			user = new User() ;
			user.setName("小一") ;
			user.setPassword("xiaoyi") ;
			user.setCreateTime(new Date()) ;
			user.setExpireTime(new Date()) ;
			/**
			 * Persistent(持久态) :
			 * 1、persistent状态的对象在数据库中有与之匹配的数据;
			 * 2、纳入了session的管理;
			 * 3、在清理缓存(脏数据检查)的时候,会和数据库同步;
			 * 4、在session关闭后,在持久态里面的内容,变为托管态,数据如果修改不会影响数据库对应值;
			 */
			session.save(user);
			
			user.setName("小二");
			/*
			 * 注意 :
			 * 在执行完tran.commit()方法后,会在控制台输出两条SQL语句,分别是
			 * Hibernate: insert into t_user (name, password, createTime, expireTime, id) values (?, ?, ?, ?, ?)
			 * Hibernate: update t_user set name=?, password=?, createTime=?, expireTime=? where id=?
			 * 
			 * session.save(user); // 执行到save()方法时插入数据库一条记录。
			 * user.setName("小二"); // 当对持久态对象进行修改时,会执行update操作。相当于在该条词句下面显示执行session.update(user);操作。 
			 */
			tran.commit() ;
			
		}catch(Exception e){
			if(tran != null){
				tran.rollback() ;
			}
			e.printStackTrace() ;
		}finally{
			HibernateUtils.closeSession(session);
		}
		/**
		 * Detached(托管态) :
		 * 1、在数据库中有与之匹配的数据;
		 * 2、没有纳入session的管理;
		 * 3、托管态对象中有主键值,瞬态的id没有主键值
		 */
		user.setName("小三") ;
		try{
			session = HibernateUtils.getSession() ;
			session.beginTransaction() ;
			/*
			 * 将detached对象重新纳入session管理,此时将变为persistent状态的对象。
			 * persistent状态的对象,在清理缓存时会和数据库同步。
			 */
			session.update(user);
			session.getTransaction().commit() ;
		}catch(Exception e){
			session.getTransaction().rollback();
			e.printStackTrace();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}
	
	/**
	 * 练习get方法
	 */
	public void testGet(){
		Session session = null ;
		try{
			session = HibernateUtils.getSession() ;
			session.beginTransaction() ;
			/**
			 * get方法的两个参数介绍:
			 * get(Class clazz, Serializable id) : clazz/要返回的持久化类型; id/必须是数据库中的主键; 返回值类型/要么是一个持久化对象的实例,要么是null ;
			 * 
			 * get简单介绍 : 
			 * 1.get加载上来的对象为持久对象 ;
			 * 2.执行get会马上发出查询语句 ;
			 * 3.get方法加载数据,如果不存在则返回null ;
			 * 
			 */
			User user = (User)session.get(User.class, "4028812b3f9e3af3013f9e3af4430001");
			if(user != null){
				/*
				 * 1.Persistent状态的对象,当对象的属性发生改变的时候 ;
				 * 2.hibernate在清理缓存(脏数据检查)的时候,会和数据库同步 ;
				 */
				System.out.println(user.getName()) ;
				user.setName("小四") ;
			}
			session.getTransaction().commit() ;
		}catch(Exception e){
			session.getTransaction().rollback();
			e.printStackTrace();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}
	
	/**
	 * 练习load方法
	 */
	public void testLoad(){
		Session session = null ;
		try{
			session = HibernateUtils.getSession() ;
			session.beginTransaction() ;
			/**
			 * load方法的两个参数介绍:
			 * load(Class clazz, Serializable id) : clazz/要返回的持久化类型; id/必须是数据库中的主键; 返回值类型/要么是一个持久化对象的实例(采用代理对象实现),要么是ObjectNotFoundException异常 ;
			 * 
			 * load简单介绍 : 
			 * 1.load加载上来的对象为持久对象 ;
			 * 2.执行get不会马上发出查询语句,因为load支持lazy(延迟加载/懒加载) ;
			 * 3.get方法加载数据,如果不存在则hibernate会抛出ObjectNotFoundException异常 ;
			 * 
			 * 什么叫lazy?
			 * 对于hibernate来说只有真正使用这个对象的时候,再创建,才真正的发出查询语句,这样主要是为了提高性能 ;
			 * lazy是hibernate中非常重要的特性 ;
			 */
			User user = (User)session.load(User.class, "4028812b3f9e8b20013f9e8b22340001");
			
			/*
			 * 1.Persistent状态的对象,当对象的属性发生改变的时候 ;
			 * 2.hibernate在清理缓存(脏数据检查)的时候,会和数据库同步 ;
			 */
			System.out.println(user.getName()) ;
			user.setName("小五") ;
			session.getTransaction().commit() ;
		}catch(Exception e){
			session.getTransaction().rollback();
			e.printStackTrace();
		}finally{
			HibernateUtils.closeSession(session);
		}
	}
}

 

HibernateUtils.java代码如下:

package com.ysj.utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;


public class HibernateUtils {
	
	/**
	 * 创建静态块,用于初始化SessionFactory
	 */
	private static SessionFactory factory ;
	static{
		try{
			// 默认获取src根目录下的 hibernate.cfg.xml配置文件
			Configuration cfg = new Configuration().configure();
			// 通过配置文件获取 sessionFactory
			factory = cfg.buildSessionFactory() ; 
		}catch(Exception e){
			e.printStackTrace() ;
		}
	}
	
	/**
	 * 获得SessionFactory
	 */
	public static SessionFactory getSessionFactory(){
		return factory ;
	}
	
	/**
	 * 获得Session
	 */
	public static Session getSession(){
		if(factory != null){
			return factory.openSession() ;
		}else{
			return null ;
		}
	}
	
	/**
	 * 关闭Session
	 */
	public static void closeSession(Session session){
		if(session != null){
			if(session.isOpen()){
				session.close() ;
				session = null ;
			}
		}
	}
}

  

 

 

附件中存放的是用MyEclipse6.0的File System导出的练习工程,有需要的可以直接下载解压导入进行测试.

附件内容包括:save,get,load,query,JUnit的练习和生命周期的介绍。下载后先读readme.txt。