在传统的JDBC操作里,通常通过sql语句查询加载所需要的数据,当sql提交之后,这些数据也就被读取待用了,而在hibernate里,我们拥有了更多的数据加载的方式。以实现不同种的需求。
hibernate支持以下四种数据加载方式:
1、及时加载(Immediate Loading)--实体加载后,立即加载其关联数据。
2、延迟加载(Lazy Loading)--实体加载后,关联数据第一次被需要时,即访问然后加载。
3、预先加载(Eager Loading)--预先加载时,实体及其关联同时读取,于及时加载类似,但是通过一条sql(基于外连接查询)
4、批量加载(Batch Loading)--相对于及时和延迟加载,采用批量方式,可以进行性能上的优化。
一、及时加载
还是引入上篇中的User表和Address表,即一个用户可有多个住址。其配置中部分关联关系如下:
-
<set
-
name="address"
-
table="Address"
-
inverse="true"
-
cascade="none"
-
sort="unsorted"
-
lazy="false"
-
>
-
<keycolumn="user_id"/>
-
<one-to-manyclass="com.entity.Address"/>
-
</set>
此时,再去做一个查询,代码如下:
-
Stringhql="fromUserwherename='Erica'";
-
-
Listlist=session.createQuery(hql).list();
-
syso("queryfinished");
-
-
Iteratorit=list.iterator();
-
while(it.hasNext()){
-
Useruesr=(User)it.next();
-
syso(user.getName());
-
syso(user.getAddresses().size());
-
}
在设置过show_sql后,控制台打印如下信息:
-
Hibernate:select......fromUseruserwhere(name='Erica')
-
Hibernate:select......fromAddressaddrwhereaddr.user_id=?
-
queryfinished
-
-
Erica
-
2
从中我们可以得出,在执行find的时候,hibernate链接调用了2条sql语句,分别完成了对User和Address对象的加载。这就是及时加载的原理,当关联主体加载时(此处则我们的User对象),hibernate会立即自动读取其关联数据并完成关联属性的填充。
二、延时加载
延时加载就是对应上面及时加载所产生的,当我们不需要关联表的数据的时候,我们不需要查询,需要的时候,再发送语句,这样就避免了过多的性能的消耗。
将上面的部分配置的lazy属性改掉(hibernate3中,lazy属性默认为true,即默认启用延迟加载),即代码如下:
-
<set
-
name="address"
-
table="Address"
-
inverse="true"
-
cascade="none"
-
sort="unsorted"
-
lazy="true"
-
>
-
<keycolumn="user_id"/>
-
<one-to-manyclass="com.entity.Address"/>
-
</set>
再次运行查询代码,我们发现控制台打印了如下的show_sql信息:
-
hibernate:select.....fromUseruserwhere(name='Erica')
-
queryfinished
-
Erica
-
-
hibernate:select.....fromAddressaddrwhereaddr.user_id=?
-
2
与上面的不同的是,当代码运行到syso(user.getName());时,hibernate只有一条语句,而然在打印地址的个数的时候,激发了第二天sql语句去查询size()的大小。这就是他的特点,当真正需要关联表的数据的时候才会去做读取操作,从而提高性能。
三、预先加载
预先加载是通过outer join完成关联数据的加载,也是通过一条sql语句完成对实体以及其关联数据的读取操作,相对应即时加载的两条或多条,无疑提高了性能,但是一般只适用于一对一的关系。对于大部分的集合类型,还是推荐使用延迟加载的模式。一般而言,outer join可以提高处理的效率,但是对于关联关系复杂的,如多层关联,hibernate会生成非常复杂的sql语句,此时,我们应该根据实际情况,判断它的实用性,同时,也可以通过设置全局变量(hibernate.max_fetch_depth)限定outer-join的关联层次,一般5层比较合适。
四、批量加载
顾名思义,就是通过批量提交多个限定条件,一次完成多个数据读取,如对于下面的sql请求:select from User where id=1; select from User where id=2经过整合后变为,select from User where id=1 or id=2。如果使用了这种方式,hibernate在进行数据操作前,会自动在当前session中寻找,是否有其他同类型的待加载的数据,如果有,则将其合并在当前的select
语句中一起提交。
在实体的配置中,我们可以在class节点下,通过设置batch-size打开批量加载机制,并限定每次批量加载的数量,代码如下:
-
<classname="User"table="Uesr"batch-size="5">
分享到:
相关推荐
**标题:“Hibernate之数据加载方式”** 在Java的持久化框架中,Hibernate是一个非常重要的工具,它简化了数据库操作,提供了对象关系映射(ORM)的功能。本篇将深入探讨Hibernate的数据加载方式,帮助开发者更好地...
1. **修改Fetch策略**:将Fetch策略设置为`fetch="join"`,即在查询主对象的同时通过JOIN查询的方式加载关联对象,这样就不会抛出延迟加载异常。 2. **禁用延迟加载**:将`lazy="false"`,这样就会在查询主对象时...
这种方式避免了在程序启动或对象创建初期就加载大量不必要的数据,从而降低了内存占用和提高了应用程序的启动速度。 ##### 2.2 Hibernate中的延迟加载实现原理 在Hibernate中,延迟加载是通过代理模式实现的。当...
本篇文章将探讨Hibernate的加载方式以及多态加载的概念。 首先,我们关注Session中的`load`和`get`方法。`load`方法是用于根据主键加载对象,它支持CGLIB懒加载(lazy loading)动态代理。当lazy属性设置为true时,...
### Hibernate延迟加载详解 #### 一、什么是延迟加载? 延迟加载是一种优化技术,在软件开发中广泛应用于各种场景,尤其在...通过合理配置和使用这一机制,可以有效地优化应用程序的数据加载流程,提高用户体验。
为了避免这种情况,Hibernate提供了延迟加载机制,使得只有在真正需要访问`addresses`时,才会去数据库查询相关的`Address`数据。 配置延迟加载的关键在于Hibernate的映射文件。在`<set>`元素中,我们通常会设置`...
综上所述,Hibernate的懒加载策略是通过代理对象和回调机制实现的,旨在按需加载数据,减少不必要的数据库操作,提高系统效率。合理使用懒加载,可以显著优化数据访问性能,但同时也需要考虑其可能带来的问题和挑战...
6. **使用Spring Data的`@EntityGraph`**:允许你在查询时定义数据加载的图形,更精细地控制加载行为。 7. **使用`@Transactional(readOnly = true)`**:对于只读操作,可以使用只读事务,这样即使在Session关闭后...
- Hibernate 自动为懒加载属性创建代理类,这些代理类在需要时才加载真实数据。 #### 四、总结 在 Hibernate 中,延迟加载技术是非常关键的一部分,它能够显著提高应用程序的性能。通过合理地选择 Fetching 策略...
《Hibernate数据持久层jar包源码解析》 在软件开发中,数据持久层是系统架构中的关键部分,它负责将应用程序的数据与数据库进行交互。Hibernate作为一款强大的Java对象关系映射(ORM)框架,极大地简化了这个过程。...
此外,理解Hibernate的“fetch plan”也很重要,这是控制加载关联对象策略的一种方式。FetchType.LAZY和FetchType.EAGER是两种主要的加载策略,前者对应懒加载,后者则是在加载主对象时同时加载关联对象。 总之,...
2. **内存优化**:避免了不必要的数据加载,节省了内存资源,防止内存溢出。 **立即加载与延迟加载的对比** - **立即加载(Eager Loading)**:使用`Session.get()`方法获取对象时,会同时加载与其关联的对象,...
- **数据加载**:首次访问代理类的非ID属性时,Hibernate会执行相应的SQL查询,从数据库中加载数据,并将代理类实例初始化为实际对象。 **5. 示例分析** 以下代码展示了延迟加载的过程: ```java tx = session....
在Java的持久化框架Hibernate中,数据访问优化是至关重要的,而抓取策略(Fetch Strategy)和懒加载(Lazy Loading)则是实现这一目标的关键技术。本文将深入探讨这两个概念,并通过具体的案例进行分析。 首先,让...
在这个场景中,"Hibernate加载数据库驱动的Jar"是指在 Hibernate 应用程序中添加 SQL Server 驱动的 JAR 文件,以便正确地连接到SQL Server数据库。 首先,我们来看一下给定的三个JAR文件: 1. **msbase.jar**:这...
这样,Hibernate可以在集合尚未被访问时,避免执行关联的数据加载。 启用集合类型的延迟加载,同样在映射配置文件中进行设置: ```xml <hibernate-mapping> ... </hibernate-mapping> ``` 考虑以下...
如果目标对象(即真实的User对象)尚未加载,Hibernate会执行SQL查询(如`select * from user where id='1'`),获取数据并构建目标对象,然后将其赋值给代理对象的`CGLIB$CALLBACK_0.target`属性。 二、集合类型的...
**延迟加载**(Lazy Loading)是Hibernate框架中的一个重要特性,主要用于优化数据库操作,减少不必要的数据加载,从而提升应用程序的性能。在传统的Eager Loading(急切加载)模式下,一旦加载了一个对象,与之相关的...