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
 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值