`

Hibernate之数据加载方式

阅读更多

Hibernate 的数据加载方式:

在JDBC的操作中,利用SQL语句加载所需要的数据进行处理,当SQL提交之后,这些数据就被读取待用;

在Hibernate中,我们有更多的选择;HIbernate中的数据记载方式:

  • 及时加载(Immeddiate Loading)

当实体加载完后,立即加载其相关联数据;

  • 延迟加载(Lazy Loading)

实体加载时,并不会立即加载其数据,而是当第一次访问的时候,在进行读取;

  • 预先加载(Eager Loading)

实体与其关联对象同时读取,这与即时加载类似,不过实体及其相关数据是通过一条SQL语句读取到得!(基于外连接);

  • 批量加载(Batch Loading)

对于即时加载和延迟加载,可以采用批量加载方式进行性能上的优化;

 

测试:

及时加载:

private static void queryTest() {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		final String hql = "from TUser where name = 'keith'";
		List<TUser> users = session.createQuery(hql).list();
		System.out.println("query finished!!!");
		Iterator<TUser> it = users.iterator();
		while (it.hasNext()) {
			TUser user = it.next();
			System.out.println("user's name:"+user.getName());
			System.out.println("user's address:"+user.getAddresses().size());
		}
		session.getTransaction().commit();
	}

 看下SQL的执行顺序:

select   tuser0_.userid as userid1_, tuser0_.name as name1_  from    TUser tuser0_   where    tuser0_.name='keith'
select   addresses0_.user_id as user3_1_1_,addresses0_.addressId as addressId1_,addresses0_.addressId as addressId0_0_,addresses0_.info as info0_0_ from   TAddress addresses0_ where addresses0_.user_id=?

query finished!!!
user's name:keith
user's address:2

 首先会加载实体类的所有内容,然后在加载其相关的数据!

 


延迟加载:

在及时加载中,当Hibernate加载TUser对象时,即同时加载了其所关联的TAddress对象,这样就可能会导致性能的降低,例如:我们只想要TUser的信息,并不想要TAddress的信息,如果按照及时加载的话,就将TAddress又查询了,导致性能降低!如果用延迟加载就可以解决这一问题;

延迟加载只需要在<set />标签中加个属性即可:

		<set name="addresses" cascade="all" lazy="true">
			<key column="user_id" />
			<one-to-many class="TAddress"/>
		</set>

 看下SQL的执行顺序:

select  tuser0_.userid as userid1_, tuser0_.name as name1_ from   TUser tuser0_   where  tuser0_.name='keith'
query finished!!!
user's name:keith
select addresses0_.user_id as user3_1_1_,addresses0_.addressId as addressId1_,addresses0_.addressId as addressId0_0_,addresses0_.info as info0_0_ from  TAddress addresses0_ where addresses0_.user_id=?

什么时候需要它,什么时候才发SQL查询它!

预先加载:

预先加载通过outer-join完成关联数据的加载,这样,通过一条SQL即可完成实体及其关联数据的读取操作 ,如果要是多条数据的话,这样会节省很大的资源;不过在集合类型中(一对多,多对一,或者多对多关系中),不推荐采用预先加载方式,对于集合,如果条件允许,我们应该尽量避免延迟加载;以避免性能生的不必要开销!

一般来说,outer-join可以高效的处理关联数据。但在一些特殊的情况下,特别是比较复杂的关联关系情况下;如多层管理,hibernate生成的的outer-join可能复杂,此时我们应该根据情况判断采用预先加载在当前环境的可用性;同时也可以通过调整全局变量限定outer-join的层次;

 

批量加载

是通过批量提交多个限定条件,一次完成多个SQL的读取;

当我们在被查询的类上添加一个 batch-size="3"属性时,指定批量查询的数量;就可以进行批量查询;

我们对TUser进行批量查询,其*.hbm.xml这样:

<hibernate-mapping package="com.keith.dataLoad">
	<class name="TUser" table="TUser" batch-size="3">
		<id name="userid">
			<generator class="native" />
		</id>
		。。。。
	</class>
</hibernate-mapping>
 

我们的测试类这样写:

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		final String hql = "from TUser";
		List<TUser> users = session.createQuery(hql).list();
		Iterator it = users.iterator();
		while (it.hasNext()) {
			TUser user = (TUser) it.next();
			System.out.println(user);
		}
		session.getTransaction().commit();
	

 但是会发出2条SQL;(因为我的SQL里就有2条数据)

输出结果:

com.keith.dataLoad.TUser@8ae45a
com.keith.dataLoad.TUser@29c204
 

 

 

 

分享到:
评论

相关推荐

    hibernate 延迟加载深入剖析

    这种方式避免了在程序启动或对象创建初期就加载大量不必要的数据,从而降低了内存占用和提高了应用程序的启动速度。 ##### 2.2 Hibernate中的延迟加载实现原理 在Hibernate中,延迟加载是通过代理模式实现的。当...

    Hibernate 延迟加载剖析与代理模式应用

    在实际运行中,当我们通过`session.get(Person.class, 1)`获取一个`Person`对象时,如果没有明确地访问`addresses`,Hibernate只会加载`Person`的基本信息,而不会加载与之关联的`Address`集合。在调试模式下,我们...

    Hibernate加载方式与多态加载分析

    本篇文章将探讨Hibernate的加载方式以及多态加载的概念。 首先,我们关注Session中的`load`和`get`方法。`load`方法是用于根据主键加载对象,它支持CGLIB懒加载(lazy loading)动态代理。当lazy属性设置为true时,...

    hibernate延迟加载解决

    ### Hibernate延迟加载详解 #### 一、什么是延迟加载? 延迟加载是一种优化技术,在软件开发中广泛应用于各种场景,尤其在...通过合理配置和使用这一机制,可以有效地优化应用程序的数据加载流程,提高用户体验。

    Hibernate的延迟加载

    这样,Hibernate可以在集合尚未被访问时,避免执行关联的数据加载。 启用集合类型的延迟加载,同样在映射配置文件中进行设置: ```xml &lt;hibernate-mapping&gt; ... &lt;/hibernate-mapping&gt; ``` 考虑以下...

    Hibernate延迟加载以及利用Spring

    1. **修改Fetch策略**:将Fetch策略设置为`fetch="join"`,即在查询主对象的同时通过JOIN查询的方式加载关联对象,这样就不会抛出延迟加载异常。 2. **禁用延迟加载**:将`lazy="false"`,这样就会在查询主对象时...

    Hibernate lazy延迟加载

    2. 当执行查询并返回实体时,如果关联对象标记为懒加载,Hibernate并不会立即执行SQL去获取关联数据,而是创建一个代理对象。这个代理对象会在真正访问关联属性时,通过执行额外的数据库查询来获取数据。 3. ...

    Flex 与 Hibernate 的延迟加载问题

    在开发Flex与Hibernate集成的应用时,延迟加载(Lazy Loading)是一个常见的挑战,因为Flex客户端无法直接理解和处理Hibernate的延迟加载机制。延迟加载是一种优化策略,它允许关联的对象在真正需要时才被加载,而...

    hibernate懒加载策略.doc

    综上所述,Hibernate的懒加载策略是通过代理对象和回调机制实现的,旨在按需加载数据,减少不必要的数据库操作,提高系统效率。合理使用懒加载,可以显著优化数据访问性能,但同时也需要考虑其可能带来的问题和挑战...

    hibernate抓取策略和懒加载案例

    在Java的持久化框架Hibernate中,数据访问优化是至关重要的,而抓取策略(Fetch Strategy)和懒加载(Lazy Loading)则是实现这一目标的关键技术。本文将深入探讨这两个概念,并通过具体的案例进行分析。 首先,让...

    Hibernate集合属性的延迟加载.doc

    在 Hibernate 框架中,延迟加载(Lazy Loading)是一种优化数据访问性能的重要技术。它允许我们只在真正需要数据时才从数据库加载,避免一次性加载大量数据导致的内存消耗和性能瓶颈。当我们处理与实体相关的集合...

    集成spring的hibernate懒加载

    6. **使用Spring Data的`@EntityGraph`**:允许你在查询时定义数据加载的图形,更精细地控制加载行为。 7. **使用`@Transactional(readOnly = true)`**:对于只读操作,可以使用只读事务,这样即使在Session关闭后...

    Hibernate 加载数据库驱动的 Jar

    在这个场景中,"Hibernate加载数据库驱动的Jar"是指在 Hibernate 应用程序中添加 SQL Server 驱动的 JAR 文件,以便正确地连接到SQL Server数据库。 首先,我们来看一下给定的三个JAR文件: 1. **msbase.jar**:这...

    Hibernate延时加载与lazy机制.doc

    - **数据加载**:首次访问代理类的非ID属性时,Hibernate会执行相应的SQL查询,从数据库中加载数据,并将代理类实例初始化为实际对象。 **5. 示例分析** 以下代码展示了延迟加载的过程: ```java tx = session....

    Hibernate数据持久层jar包源码解析

    《Hibernate数据持久层jar包源码解析》 在软件开发中,数据持久层是系统架构中的关键部分,它负责将应用程序的数据与数据库进行交互。Hibernate作为一款强大的Java对象关系映射(ORM)框架,极大地简化了这个过程。...

    Hibernate 使用缓存时,数据同步问题

    2. **使用`refresh()`方法**:调用实体对象的`refresh()`方法可以强制Hibernate从数据库中重新加载该对象的状态,以覆盖缓存中的陈旧数据。 3. **设置缓存模式**:在查询时,可以设置`CacheMode.REFRESH`,强制...

    hibernate延迟加载技术详细解

    - 解决方法之一是在关闭 Session 之前加载关联对象,如通过 `session.evict(user)` 或 `Hibernate.initialize(user.getPermissions())`。 - 另一种解决办法是在 HQL 查询或 Criteria 查询中使用 Join Fetching。 ...

Global site tag (gtag.js) - Google Analytics