Hibernate基于配置文件(三)get()与load()的区别

本文详细介绍了Hibernate中的懒加载策略,对比get()与load()的区别,解释了懒加载的工作原理及其实现机制,并提供了多个示例代码片段来演示不同场景下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,Hibernate默认开启懒加载策略!是Hibernate推崇的一种提高性能的方法!

 

get()与load()都用于加载已存在id值的对象到内存中

区别:

get()

get()马上发出SQL语句查询相关对象

get()操作的对象如果不存在,抛NullPointerException

get()返回的是原始对象

 

load()

load()使用Hibernate的懒加载策略,除非调用到对象的非id属性,否则不会发出查询语句

load()加载的对象如果不存在,抛ObjectNotFountException

load()返回的是1个代理对象

如果懒加载策略被取消(lazy=false),则load()会立即发出SQL查询语句,而且不再返回代理对象

 

懒加载---重点

1. 实体类一定要有无参构造方法!
2. 任何一个实体类都必须有唯一的数据库标识值(逻辑主键,不要用业务主键)
3. 数据库标识不允许修改---所以不能将业务属性定义为主键
4. 主键-非空、唯一
5. 懒加载只有在使用load()的前提下,且lazy=true,且session未关闭前才会生效
6. 如果session已经关闭,使用懒加载机制会发生异常:LazyInitializationException: could not initialize proxy - no Session
7. get()与懒加载机制无关,即使lazy=true,懒加载也不会生效
8. 懒加载实现原理---代理对象
9. *只要调用user中除了getId()之外的其他任何方法(只要是在User类中定义的方法,包括从Object中继承的toString()),
    hibernate就认为使用到了对象的非id属性,这是就会立即发出select语句从数据库获取对象属性!
    注意:即使是调用setId()都会促发hibernate发出select查询!但是,一般都不使用setId(),因为:修改主键值是什么行为呢?

10. 延迟加载的好处:只需要加载到对象,而不需要对象的属性,使用懒加载机制就能避免发出select查询语句,这样提高了程序执行效率!!!
    关联映射时,就用load(),不用hibernate发出查询语句!
    
11. 延迟发出:
        hibernate的性能调整方案!
        比如:insert\delete 语句在commit之后才被发出(一批数据与数据库进行通信)--这就是延迟,这就是性能调整!
        建议多用load(),充分利用hibernate的性能调整!
12. get时,如果对象不存在,主键id不存在,在get时会马上抛空指针异常
    load时,对象不存在,会延迟到真正加载对象(发出select语句时)才会抛异常,即异常被延迟抛出,因为前面还没有访问数据库,怎么抛异常呢!
13. 如果lazy=false,则不会有代理对象!

 

 

 

package org.leadfar.hibernate.model;

import java.util.Date;

import junit.framework.TestCase;

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

public class UserTest04 extends TestCase {
	
	//session未关闭,lazy=true,使用load()懒加载机制生效。
	//直到真正使用到对象非id属性时才会发出select语句
	//或者说调用了User类中非getId()的任何方法,hibernate就会发出select语句
	//注意:调用setId()也会促使hibernate发出select语句,但是修改主键为其它值,则会发生异常!
	public void testUser_Lazy01() throws Exception {
		//默认读取类路径根目录下的hibernate.cfg.xml配置文件
		Configuration cfg = new Configuration().configure();
		
		//创建SessionFactory
		SessionFactory sfactory = cfg.buildSessionFactory();
		
		//创建Hibernate Session
		Session session = sfactory.openSession();
		
		try {
			//开启事务
			session.beginTransaction();
			
			//使用load方法获取对象属性,当lazy="true"时,访问id属性是不会发出select语句的
			//因为id作为主键,在load方法中已经指明了,所以hibernate不用访问数据库就能直到id值是多少
			User user =(User)session.load(User.class, 109);
			
			System.out.println(user.getId());
			System.out.println(user.getName());
			
			//提交事务
			session.getTransaction().commit();
			
		} catch(Exception e) {
			e.printStackTrace();
			//出现异常,回滚事务
			session.getTransaction().rollback();
		} finally {
			//关闭session
			session.close();//session关闭之后,user对象处于离线Detached状态
		}
	}
	
	//session未关闭,lazy=false,懒加载不会生效
	public void testUser_Lazy02() throws Exception {
		//默认读取类路径根目录下的hibernate.cfg.xml配置文件
		Configuration cfg = new Configuration().configure();
		
		//创建SessionFactory
		SessionFactory sfactory = cfg.buildSessionFactory();
		
		//创建Hibernate Session
		Session session = sfactory.openSession();
		
		try {
			//开启事务
			session.beginTransaction();
			
			//使用load方法获取对象属性,当lazy="false"时,hibernate会马上发出select语句,即不会延迟加载
			//相当于使用get()方法没有延迟加载机制
			//使用get()即使lazy=true,懒加载机制也不会生效。
			//懒加载只有在使用load的前提下,且lazy=true才会生效
			User user =(User)session.load(User.class, 109);
			
			System.out.println(user.getId());
			System.out.println(user.getName());
			
			//提交事务
			session.getTransaction().commit();
			
		} catch(Exception e) {
			e.printStackTrace();
			//出现异常,回滚事务
			session.getTransaction().rollback();
		} finally {
			//关闭session
			session.close();//session关闭之后,user对象处于离线Detached状态
		}
	}
	
	//使用懒加载机制,在session关闭之后,访问对象属性,会发生LazyInitializationException异常
	//session关闭之后才真正访问到对象非id属性时,这时再加载就会发生异常!
	//该异常发生的前提:1.lazy=true 2.session有效期间没有发出select语句
	//3,在session关闭后,才需要hibernate发出select语句,但是此时session已经关闭,所以异常发生了!
	public void testUser_Lazy03() throws Exception {
		//默认读取类路径根目录下的hibernate.cfg.xml配置文件
		Configuration cfg = new Configuration().configure();
		
		//创建SessionFactory
		SessionFactory sfactory = cfg.buildSessionFactory();
		
		//创建Hibernate Session
		Session session = sfactory.openSession();
		User user = null;
		try {
			//开启事务
			session.beginTransaction();
			
			//使用load方法获取对象属性,当lazy="false"时,hibernate会马上发出select语句,即不会延迟加载
			//相当于使用get()方法没有延迟加载机制
			//使用get()即使lazy=true,懒加载机制也不会生效。
			//懒加载只有在使用load的前提下,且lazy=true,且session未关闭前才会生效
			user =(User)session.load(User.class, 109);

			System.out.println(user.getId());

			
			//提交事务
			session.getTransaction().commit();
			
		} catch(Exception e) {
			e.printStackTrace();
			//出现异常,回滚事务
			session.getTransaction().rollback();
		} finally {
			//关闭session
			session.close();//session关闭之后,user对象处于离线Detached状态
		}
		//session关闭之后,懒加载失效
		System.out.println(user.getName());
		System.out.println(user.getBirthday());
		//org.hibernate.LazyInitializationException: could not initialize proxy - no Session
		
	}
	
	
	//加载对象的时候不能使用setId()方法改变对象的id主键值,否则引发异常
	//当然,使用setId()修改为同一个值不会引发异常,会促发hibernate发出select语句!
	public void testUser_Lazy04() throws Exception {
		//默认读取类路径根目录下的hibernate.cfg.xml配置文件
		Configuration cfg = new Configuration().configure();
		
		//创建SessionFactory
		SessionFactory sfactory = cfg.buildSessionFactory();
		
		//创建Hibernate Session
		Session session = sfactory.openSession();
		User user = null;
		try {
			//开启事务
			session.beginTransaction();
			
			//加载对象时,修改了id主键,commit的时候会报异常
			user =(User)session.load(User.class, 109);
			
			System.out.println(user.getId());
			user.setId(110);//setId()方法会促发hibernate发出select语句!!!!!
			//user.setId(110);--->引发异常,主键值被修改了
			//注意:setId()调用会不论异常发生与否,hibernate都会发出select语句查询数据库并通过setX()设置对象属性
			
			//提交事务
			session.getTransaction().commit();
			
		} catch(Exception e) {
			e.printStackTrace();
			//出现异常,回滚事务
			session.getTransaction().rollback();
		} finally {
			//关闭session
			session.close();//session关闭之后,user对象处于离线Detached状态
		}
		//即使调用setId()引发了异常,下面一样可以访问到对象属性值
		//同时,发生异常的话,下面获取到的id值一定是新值
		//如果还是以前的值,那么修改的id值就是同一个值,即没有发生异常!!!
		System.out.println(user.getId());
		System.out.println(user.getName());
		System.out.println(user.getMoney());
	}
	
	//get()加载对象,如果对象不存在时,即使没有使用到对象的非id属性,也会抛异常
	//因为一旦get,就会发出select语句
	public void testUser_Lazy05() throws Exception {
		//默认读取类路径根目录下的hibernate.cfg.xml配置文件
		Configuration cfg = new Configuration().configure();
		
		//创建SessionFactory
		SessionFactory sfactory = cfg.buildSessionFactory();
		
		//创建Hibernate Session
		Session session = sfactory.openSession();
		User user = null;
		try {
			//开启事务
			session.beginTransaction();
			
			//加载对象时,主键不存在,执行到下一句时,异常抛出
			user =(User)session.get(User.class, 200);
			System.out.println(user.getMoney());
			System.out.println(user.getId());
			
			//提交事务
			session.getTransaction().commit();
			
		} catch(Exception e) {
			e.printStackTrace();
			//出现异常,回滚事务
			session.getTransaction().rollback();
		} finally {
			//关闭session
			session.close();//session关闭之后,user对象处于离线Detached状态
		}
	}
	
	
	//load()加载对象,如果对象不存在时,又没有使用到对象的其他非id属性,不会发生异常
	//因为没有发出select语句查询数据库,所以不会有异常发生
	//如果使用到了其他属性,则异常会延迟到真正发select语句后才会抛出!
	public void testUser_Lazy06() throws Exception {
		//默认读取类路径根目录下的hibernate.cfg.xml配置文件
		Configuration cfg = new Configuration().configure();
		
		//创建SessionFactory
		SessionFactory sfactory = cfg.buildSessionFactory();
		
		//创建Hibernate Session
		Session session = sfactory.openSession();
		User user = null;
		try {
			//开启事务
			session.beginTransaction();
			
			//加载对象时,修改了id主键,commit的时候会报异常
			user =(User)session.load(User.class, 200);
		
			System.out.println(user.getId());
			
			//提交事务
			session.getTransaction().commit();
			
		} catch(Exception e) {
			e.printStackTrace();
			//出现异常,回滚事务
			session.getTransaction().rollback();
		} finally {
			//关闭session
			session.close();//session关闭之后,user对象处于离线Detached状态
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值