`
schy_hqh
  • 浏览: 542390 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

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

 
阅读更多

首先,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状态
		}
	}
}

 

分享到:
评论

相关推荐

    hibernate基础教程

    第一步:修改Hibernate配置文件,启用Hibernate的第二级缓存.在配置文件中加入EhCache缓存插件的实现类. 第二步:拷贝ehcache.xml文件到类路径下(位于Hibernate3的etc文件夹下) 第三步:对需要进行缓存的...

    hibernate操作数据库笔记

    //该方法将到classpath下解析hibernate.cfg.xml中的配置,如果不用Hibernate默认的配置文件名和路径,可在该方法中指定Hibernate配置文件的名称和路径 2.用Configuration对象获取SessionFactory和Session对象:...

    hibernate 3中的缓存小结

    当应用程序调用Session的save()、update()、savaeOrUpdate()、get()或load(),以及调用查询接口的list()、iterate()或filter()方法时,如果在Session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到CUSTOMERS表  3.5 通过...

    精通hibernate:对象持久化技术孙卫琴第二版part2

    3.1 创建Hibernate的配置文件 47 3.2 创建持久化类 48 3.3 创建数据库Schema 51 3.4 创建对象-关系映射文件 52 3.4.1 映射文件的文档类型定义(DTD) 52 3.4.2 把Customer持久化类映射到CUSTOMERS表 54 3.5 ...

    ssh(structs,spring,hibernate)框架中的上传下载

     由于Spring通过代理Hibernate完成数据层的操作,所以原Hibernate的配置文件hibernate.cfg.xml的信息也转移到Spring的配置文件中:  代码 4 Spring中有关Hibernate的配置信息 1. 2. !-- 数据源的配置 //--> 3. ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到CUSTOMERS表  3.5 通过...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到CUSTOMERS表  3.5 通过...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     3.1 创建Hibernate的配置文件  3.2 创建持久化类  3.3 创建数据库Schema  3.4 创建对象-关系映射文件  3.4.1 映射文件的文档类型定义(DTD)  3.4.2 把Customer持久化类映射到CUSTOMERS表  3.5 通过...

    精通Hibernate:对象持久化技术第二版part3

    3.1 创建Hibernate的配置文件 47 3.2 创建持久化类 48 3.3 创建数据库Schema 51 3.4 创建对象-关系映射文件 52 3.4.1 映射文件的文档类型定义(DTD) 52 3.4.2 把Customer持久化类映射到CUSTOMERS表 54 3.5 ...

    低清版 大型门户网站是这样炼成的.pdf

    4.2.4 hibernate的映射配置文件 201 4.2.5 体验hibernate(会员管理) 203 4.3 hibernate的映射机制 212 4.3.1 hibernate的基本映射数据类型 212 4.3.2 hibernate的主键映射 218 4.3.3 hibernate的实体映射 228...

    DWR.xml配置文件说明书(含源码)

    DWR.xml配置文件说明书 1、 建立dwr.xml 配置文件 任何一个dwr.xml的文件都需要包含DWR DOCTYPE的声明行,格式如下: <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" ...

    Java面试宝典2020修订版V1.0.1.doc

    14、Hibernate中load和get的区别? 92 15、Hibernate的工作原理? 92 16、hibernate优缺点? 92 17、Hibernate是如何延迟加载的? 93 18、如果优化Hibernate? 93 19、什么是ORM? 94 20、Hibernate的主键生成策略? ...

    Java面试宝典2010版

    9、hibernate中的update()和saveOrUpdate()的区别,session的load()和get()的区别。 10、简述 Hibernate 和 JDBC 的优缺点? 如何书写一个 one to many 配置文件. 11、iBatis与Hibernate有什么不同? 12、写...

    最新Java面试宝典pdf版

    9、hibernate中的update()和saveOrUpdate()的区别,session的load()和get()的区别。 122 10、简述 Hibernate 和 JDBC 的优缺点? 如何书写一个 one to many 配置文件. 122 11、iBatis与Hibernate有什么不同? 122 12、...

    Java面试笔试资料大全

    9、hibernate中的update()和saveOrUpdate()的区别,session的load()和get()的区别。 122 10、简述 Hibernate 和 JDBC 的优缺点? 如何书写一个 one to many 配置文件. 122 11、iBatis与Hibernate有什么不同? 122 12、...

    jdbc基础和参考

    3.hibernate的配置文件(hibernate.cfg.xml)得存在 4.POJO.hbm.xml文件存在 5.hibernate的jar包以及数据库的驱动包存在 Hibernate的编程: 1.构建Configuration对象读取配置文件 2.读取映射文件 3.构建SessionFactory...

    JAVA面试宝典2010

    9、hibernate中的update()和saveOrUpdate()的区别,session的load()和get()的区别。 122 10、简述 Hibernate 和 JDBC 的优缺点? 如何书写一个 one to many 配置文件. 122 11、iBatis与Hibernate有什么不同? 122 12、...

    Java面试宝典-经典

    9、hibernate中的update()和saveOrUpdate()的区别,session的load()和get()的区别。 122 10、简述 Hibernate 和 JDBC 的优缺点? 如何书写一个 one to many 配置文件. 122 11、iBatis与Hibernate有什么不同? 122 12、...

Global site tag (gtag.js) - Google Analytics