`
zfwdl2005
  • 浏览: 237599 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Hibernate 的get与load方法的区别

阅读更多
很多时候,大家愿意说hibernate的性能差问题,其实每个技术都其精秒之处,现在将小弟对hibernate中get() load()方法的区别做一些分析:

get 立即加载

load 延迟加载

    但到底立即或延迟加载的是什么?这是值得细细分析的问题。

    下面以分销商(Distributor)、客户(Customer)的一对多关系来举例分析

1.Distributor.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
	package="entity">

	<class name="Distributor" table="distributor">
		<id name="id">
			<generator class="uuid.hex"/>
		</id>
		<property name="name"/>
		<property name="no"/>
		<set name="cs" lazy="true">
			<key column="d_id"></key>
			<one-to-many class="Customer"/>
		</set>
	</class>
</hibernate-mapping>

2.Customer.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
	package="entity">
	<class name="Customer" table="customer">
		<id name="id">
			<generator class="uuid.hex"/>
		</id>
		<property name="name"/>
		<property name="age"/>
		<many-to-one name="distributor" class="Distributor"></many-to-one>
	</class>
</hibernate-mapping>

3.QueryTest.java
public class QueryTest {
	public static void main(String[] args) {
		Configuration cfg = new Configuration().configure();
		SessionFactory sf = cfg.buildSessionFactory();
		Session session =  sf.openSession();
		session.beginTransaction();
		Distributor d = (Distributor) session.load(Distributor.class, "297e467b30eaf6110130eaf6151b0001");
		session.getTransaction().commit();
		session.close();
		System.out.println("d.getName=>"+d.getName());
		for(Customer c: d.getCs()){
			System.out.println(c.getName());
		}
	}
}

4:分析:
   4.1 QueryTest.java中,我们使用load方法查询出的数据,并没有在session关闭前取出数据,而是将取数据的代码写在session.close()之后,也就是说当session关闭后,我们再测试,是不是能够到到它里面的数据,结果显示:即取不到Distributor对象的基本信息,也取不到关系对象的Customer集合信息(这个当然取不到了,连Distributor都取不到就没有可能取到集合)
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Exception in thread "main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
	at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:132)
	at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:174)
	at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
	at entity.Distributor_$$_javassist_1.getName(Distributor_$$_javassist_1.java)
	at QueryTest.main(QueryTest.java:30)

  4.2 如果将上面的load方法改为get方法,则结果马上发生变化,结果显示:Distributor的基本信息取值没有问题,而它的关联集合中的数据无法取到。
因此,通过以上两个的测试,我们可以得出结论【load方法延迟加载,load方法在调用的时候得到的只是一个代理对象,真正去访问数据的时候才会发送sql语句去查询;get方法立即加载,当调用的时候,就已经执行了sql语句,不管是否去取值,都已经从数据中取得并放在对象当中】
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
Hibernate: select distributo0_.id as id1_0_, distributo0_.name as name1_0_, distributo0_.no as no1_0_ from distributor distributo0_ where distributo0_.id=?
d.getName=>分销商
Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: entity.Distributor.cs, no session or session was closed
	at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
	at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
	at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
	at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
	at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)
	at QueryTest.main(QueryTest.java:31)

  4.3 lazy的说明:本例中的lazy本身与load get方法没有什么关系,但往往有朋友认为对于是否立即加载的对象看成是关联关系存在而造成的差异,这里明确说明【没有】。对于延迟加载的lazy参数,在这儿从编程的角度作一个说明:一般编程中,我们为了图方便,可以直接在配置文件中配置lazy="false",让其立即加载,但这样会影响性能,可能有时候我们并不需要它的关联集合,却已经把sql发送过去了,业内的朋友的编程经验是:不做关联关系,在程序中自己控制关联关系,这种想法是可以的,但就有些out了,本身hibernate自己已经有了这样一个关联查询机制,现在却自己实现,还不如不用;个人的经验:lazy在配置文件中设置为true,使其延迟加载,而需要立即加载的时候,则使用局部立即加载,这样,在性能上就可以大大的优化。
分享到:
评论

相关推荐

    hibernate get load区别

    ### Hibernate中的Get与Load方法详解 #### 概述 在Hibernate框架中,`get`与`load`方法都是用于从数据库加载实体对象的常用手段。然而,这两种方法在实现细节上有着本质的区别,这些差异主要体现在对缓存的利用、...

    Hibernate的get和load方法的区别

    在Java的持久化框架Hibernate中,`get`和`load`方法都是用于从数据库中获取对象,但它们之间存在一些重要的区别。理解这些差异对于优化应用程序的性能和避免潜在问题至关重要。 首先,让我们来深入了解一下`get`...

    hibernate中get和load方法的区别

    在Java的持久化框架Hibernate中,`get`和`load`方法都是用于从数据库中获取对象,但它们之间存在一些重要的区别。理解这些差异对于优化应用程序的性能和避免潜在问题至关重要。 首先,`get`方法是直接从数据库中...

    Hibernate查询 load与get的区别及其它查询测试

    `load`和`get`方法是Hibernate中用于检索实体的两种主要方式,它们都是从Session接口中调用,但有明显的区别和各自的适用场景。 1. `load`方法: - `load`方法主要用于根据主键加载对象,它返回一个代理对象,而...

    hibernate 三种 查询 方式 load与get的区别

    本篇文章将详细解析Hibernate中的三种主要查询方式——HQL(Hibernate Query Language)、Criteria API和Query API,并着重讨论`load()`与`get()`方法的区别。 一、HQL查询 Hibernate Query Language(HQL)是...

    hibernate中get和load的区别共5页.pdf

    总的来说,理解Hibernate的`get`和`load`方法的区别是优化数据库操作、提高应用程序性能的关键。开发者应当根据实际情况灵活选择,避免不必要的性能开销,同时充分利用Hibernate的缓存机制来提升应用的响应速度。

    session的get与load比较

    本文将深入探讨`get`与`load`两种方法的区别及其应用场景。 #### 一、基本概念 在Hibernate中,`Session`接口提供了`get`和`load`两种方法来获取数据库中的实体对象。 1. **get** 方法:尝试从当前Session的缓存...

    Hibernate中get和load方法的区别以及close(),clear()、evict()等的区别

    本文主要讨论了`get`、`load`方法以及`flush`、`clear`、`evict`等方法的区别。 首先,让我们关注`get`和`load`的区别: 1. **返回结果对比**: - `load`方法如果找不到对应的记录,会抛出`org.hibernate....

    hibernate get/load/saveOrUpdate/statistics

    博文链接:https://log-cd.iteye.com/blog/205166

    Hibernate中load方法与get方法的区别

    在Hibernate框架中,`load()`和`get()`都是用于从数据库中检索对象的方法,但它们在功能和行为上存在显著的差异。理解这些差异对于优化应用程序的性能和处理潜在异常至关重要。 首先,`load()`方法执行延迟加载策略...

    Hibernate中Session.get()方法和load()方法的详细比较

    Hibernate中Session.get()方法和load()方法是两个常用的数据访问方法,但它们之间有着本质的区别。 首先,从返回值上看,get()方法直接返回实体类,如果查不到数据则返回null。load()方法则返回一个实体代理对象,...

    Hibernate中get()和load()的区别.docx

    在Hibernate ORM框架中,获取持久化对象的两种主要方法是`get()`和`load()`。它们都是用来根据主键ID查询数据库中的实体对象,但两者在执行机制和返回结果上有显著的区别。 1. `get()`方法 当调用`session.get()`...

    Hibernate方法总结

    在Java持久化框架Hibernate中,HibernateTemplate是一个便捷的工具类,它封装了常见的数据库操作,使得开发者能够更方便地与数据库交互。以下是对标题和描述中提到的HibernateTemplate方法的详细总结: A. `get` 和...

    hibernate难点重点笔记

    本文将针对Hibernate中的几个重要概念进行详细讲解,包括主键生成策略、get()与load()的区别以及二级缓存的使用。 首先,探讨的是Hibernate中的主键生成策略。在Hibernate中,主键的生成主要有三种方式:uuid、...

    Hibernate入门文档

    Hibernate 难点解析: hibernate中uuid和...Hibernate get与load的区别 hibernate二级缓存中list和iterator的用法 Hibernate中的对象有三种状态: lock和update区别 save 和update区别 update 和saveOrUpdate区别

    Hiernate里get和load的区别

    在Hibernate框架中,`get` 和 `load` 都是用来从数据库中获取对象的方法,但它们之间存在一些关键差异。了解这些差异对于高效地使用Hibernate至关重要。 首先,让我们来看看这两个方法的基本用法: 1. `get` 方法...

    实现自己的Hibernate框架之Session 方法实现

    get()方法直接返回对象,而load()则返回一个代理对象,只有在需要时才从数据库加载数据,以实现懒加载。 5. **查询(createQuery()、createSQLQuery()、find()等)**:Hibernate提供丰富的查询方式,如HQL...

Global site tag (gtag.js) - Google Analytics