`
zhouxianglh
  • 浏览: 268241 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

(4)Hibernate中的many-to-one和one-to-many关系

阅读更多

今天小节了一下:

1 Hibernate 中查询.

2 inverse 和 cascade的对比.

3 二级缓存和查询缓存的使用。

 

hibernate.cfg.xml 如下:

<!-- 指定使用 Echache做缓存提供者 -->
<property name="hibernate.cache.provider_class">
	org.hibernate.cache.EhCacheProvider
</property>


<!-- 使用查询缓存(查询缓存在二级缓存的基础上使用) -->
<property name="hibernate.cache.use_query_cache">true</property>

 

ehcache.xml(用于二级缓存)如下:

<ehcache>
	<!-- 内存中存不下时存放在硬盘的位置 -->
	<diskStore path="F:\\temp" />

	<defaultCache maxElementsInMemory="2000" eternal="false"
		timeToIdleSeconds="1000" timeToLiveSeconds="1000"
		overflowToDisk="true">
	</defaultCache>

	<cache name="com.isw2.bo.TelBO" maxElementsInMemory="500"
		eternal="false" timeToIdleSeconds="1000" timeToLiveSeconds="1000"
		overflowToDisk="true" />
	<cache name="com.isw2.bo.UserBO" maxElementsInMemory="500"
		eternal="false" timeToIdleSeconds="1000" timeToLiveSeconds="1000"
		overflowToDisk="true" />
	<cache name="com.isw2.bo.UserBO.telBOs" maxElementsInMemory="500"
		eternal="false" timeToIdleSeconds="1000" timeToLiveSeconds="1000"
		overflowToDisk="true" />

	<cache name="org.hibernate.cache.StandardQueryCache"
		maxElementsInMemory="100" eternal="true" overflowToDisk="true">
	</cache>

	<cache name="org.hibernate.cache.UpdateTimestampsCache"
		maxElementsInMemory="100" eternal="true" overflowToDisk="true">
	</cache>
</ehcache>

 TelBO.hbm.xml 如下:

<class name="com.isw2.bo.TelBO" table="t_tel" catalog="many_to_one"
	lazy="true">
	<!-- 读写策略 -->
	<cache usage="read-write" />


	<id name="telId" column="telId">
		<generator class="native"></generator>
	</id>
	<property name="telNumber" column="telNumber" length="32"
		type="string">
	</property>
	<many-to-one name="userBO" fetch="select"
		column="userId" lazy="proxy">
	</many-to-one>


</class>

 UserBO.hbm.xml如下:

<class name="com.isw2.bo.UserBO" table="t_user"
	catalog="many_to_one" lazy="true">
	<!-- 使用二级缓存 -->
	<cache usage="read-write" />


	<id name="userId" column="userId">
		<generator class="native"></generator>
	</id>
	<property name="userName" column="userName" length="32"
		type="string">
	</property>
	<set name="telBOs" fetch="select" cascade="all" lazy="true"
		inverse="true">
		<!-- 使用二级缓存 -->
		<cache usage="read-write" />


		<key column="userId"></key>
		<one-to-many class="com.isw2.bo.TelBO" />
	</set>


</class>
 
/**
 * 关于 inverse="true"
 */
public void update() {
	Session session = HibernateSessionFactory.getSession();
	Transaction tr = session.beginTransaction();
	Query query = session.createQuery("from UserBO ub where ub.userId = 7");
	UserBO userBO = (UserBO) query.uniqueResult();
	TelBO telBO = new TelBO("9058492", userBO);
	userBO.getTelBOs().add(telBO);
	session.update(userBO);
	tr.commit();
	session.close();
	/**
	 * 在one-to-many 中 设置 inverse="true" 表示由many方维护数据间的关系. 注意: 区别于 cascade
	 * 表示需要哪些维护数据间的关系(all:所有情况下均进行关联操作;
	 * none:所有情况下均不进行关联操作,这是默认值;save-update:在执行save/update/saveOrUpdate时进行关联操作;
	 * delete:在执行delete时进行关联操作。 )
	 * 
	 * 对下面的操作分析可知,当由one方维护时数据先存入数据库,然后根据 one 执行更新操作;
	 * 由many 方维护时,数据先查询,然后根据查询结果存入数据库
	 */
	/**
	 * inverse="true" 时操作如下: 
	 * Hibernate: select userbo0_.userId as userId1_,
	 * userbo0_.userName as userName1_ from many_to_one.t_user userbo0_
	 * where userbo0_.userId=7 
	 * 
	 * Hibernate: select telbos0_.userId as
	 * userId1_, telbos0_.telId as telId1_, telbos0_.telId as telId0_0_,
	 * telbos0_.telNumber as telNumber0_0_, telbos0_.userId as userId0_0_
	 * from many_to_one.t_tel telbos0_ where telbos0_.userId=? 
	 * 
	 * Hibernate:
	 * insert into many_to_one.t_tel (telNumber, userId) values (?, ?)
	 * 
	 * 
	 * 
	 * inverse="false" 时操作如下: 
	 * 
	 * Hibernate: select userbo0_.userId as userId1_,
	 * userbo0_.userName as userName1_ from many_to_one.t_user userbo0_
	 * where userbo0_.userId=7 
	 * 
	 * Hibernate: select telbos0_.userId as
	 * userId1_, telbos0_.telId as telId1_, telbos0_.telId as telId0_0_,
	 * telbos0_.telNumber as telNumber0_0_, telbos0_.userId as userId0_0_
	 * from many_to_one.t_tel telbos0_ where telbos0_.userId=? 
	 * 
	 * Hibernate:insert into many_to_one.t_tel (telNumber, userId) values (?, ?)
	 * Hibernate: update many_to_one.t_tel set userId=? where telId=?
	 */
}

/**
 * 根据Bean 查询对象
 */
public void findByEntity() {
	Session session = HibernateSessionFactory.getSession();
	UserBO userBO = (UserBO) session.load(UserBO.class, new Long(7));
	/**
	 * Query query = session.createQuery("from TelBO tb where tb.userBO =
	 * ?"); query.setParameter(0, userBO); TelBO telBO = new TelBO();
	 * telBO.setTelNumber("591201270");
	 */
	// 这里把UserBO 当作Bean 来使用,userBO.getUserId 在这里可以提供参数注意:userId
	Query query = session.createQuery("from TelBO tb "
			+ "where tb.telId =:userId");
	query.setProperties(userBO);
	System.out.println(query.setMaxResults(1).uniqueResult());
	session.close();
}

/**
 * 根据 Alias 联合查询(distinct 无法解决)
 */
public void findByJoinAlias() {
	Session session = HibernateSessionFactory.getSession();
	Criteria cr = session.createCriteria(UserBO.class);
	cr.createAlias("telBOs", "tb");// 别名的使用
	cr.add(Restrictions.like("tb.telNumber", "%"));
	// //这样查询结果仅有userName 一个字段
	// cr.setProjection(Projections.distinct(Projections.property("userName")));

	// //这只是在结果集中做了处理分页时无法使用
	// cr.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
	List list = cr.list();
	for (Object object : list) {
		System.out.println(object);
	}
	session.close();
}

/**
 * 通过HQL 联合查询
 */
public void findByJoinHQL() {
	Session session = HibernateSessionFactory.getSession();
	// fetch 查询和 非fetch 查询, SQL语句相同,不同的是前者以 对象形式 返回,后者以数组形式返回
	// Query query = session.createQuery("from UserBO ub inner join
	// ub.telBOs");

	// Query query = session
	// .createQuery("from UserBO ub inner join fetch ub.telBOs");
	Query query = session
			.createQuery("select distinct ub from UserBO ub inner join fetch ub.telBOs");

	List list = query.list();
	for (Object object : list) {
		System.out.println(object);
	}
	session.close();
}

/**
 * 使用二级缓存(批量更新数据时为提高效率通过session.setCacheMode设置缓存模式)
 */
public void testCache() {
	System.out.println("开始查询.....");
	Session session = HibernateSessionFactory.getSession();
	Query query = session.createQuery("from UserBO");
	List list = query.list();
	for (Object object : list) {
		System.out.println(object);
	}
	session.close();
	System.out.println("使用二级缓存......");
	/**
	 * 查询SQL: Hibernate: select userbo0_.userId as col_0_0_ from
	 * many_to_one.t_user userbo0_
	 * 
	 * 这里先查询Id 然后在缓存中根据id查找. 这里要注意,使用的是query.iterate.
	 * 因为它会先查询Id,再根据Id查询对象,如二级缓存中有则直接取,否则就去数据库查询.
	 * 之前一次查询后数据已放入二级缓存,第二次就没有查询数据库.
	 * 
	 * 集合的缓存中存放的是Id,然后根据Id 查询二级缓存
	 * 
	 * 如果用query.list 则要使用查询缓存.
	 */
	session = HibernateSessionFactory.getSession();
	query = session.createQuery("from UserBO");
	Iterator<Object> iterator = query.iterate();
	for (; iterator.hasNext();) {
		Object object = iterator.next();
		System.out.println(object);
	}
	session.close();
}

/**
 * 使用查询缓存
 */
public void testSearchCache() {
	System.out.println("开始查询.....");
	Session session = HibernateSessionFactory.getSession();
	Query query = session.createQuery("from UserBO");
	// 设置使用查询缓存(查询缓存默认不使用,这里要显示启动)
	query.setCacheable(true);
	// 设置缓存区域
	query.setCacheRegion("com.isw2.bo.UserBO");
	// ------------------------------------
	List list = query.list();
	for (Object object : list) {
		System.out.println(object);
	}
	session.close();
	System.out.println("使用查询缓存......");
	session = HibernateSessionFactory.getSession();
	query = session.createQuery("from UserBO");
	// 设置使用查询缓存(两次使用同样的缓存区域)
	query.setCacheable(true);
	query.setCacheRegion("com.isw2.bo.UserBO");
	// ------------------------------------
	list = query.list();
	for (Object object : list) {
		System.out.println(object);
	}
	/**
	 * 在这里查询缓存类似于集合缓存。通过查询语句和 Id 集的方式存放查询结果,然后在二级缓存中查询结果
	 */
}
 

这里以又向关联为主。二级缓存因为命中率不高使用的不多,自己也不是很熟。

参考:

http://www.iteye.com/topic/18904

http://rujingzhang.iteye.com/blog/219487

http://www.blogjava.net/i369/articles/219408.html

分享到:
评论

相关推荐

    Hibernate one-to-many / many-to-one关系映射

    总结,Hibernate的one-to-many和many-to-one关系映射是数据库对象关联的基础,理解和熟练掌握它们能帮助开发者更高效地设计和实现Java持久化层。通过合理的配置和实践,可以构建出高性能、易于维护的数据访问层。

    hibernate many-to-one(多对一)及 cascade(级联).doc

    综上所述,`many-to-one` 和 `cascade` 是Hibernate中非常重要的概念,它们能够帮助开发者更高效地管理实体之间的关系。然而,在实际应用中,需要根据具体的业务需求和场景来合理选择和配置这些功能,避免不必要的...

    Hibernate中many-to-one关系的编写_远航的水手

    Hibernate中many-to-one关系的编写_远航的水手

    Hibernate中many-to-one关系的编写_远航的水手.htm

    Hibernate中many-to-one关系的编写_远航的水手.htm

    Hibernate Mapping Many-to-One 实例 内附源代码及附件下载

    本实例将详细讲解如何在Hibernate中实现Many-to-One关系映射,这是一种常见的数据库关联,表示一个实体可以与多个其他实体相关联。 在Many-to-One关系中,通常一个实体(如部门)可以有多个相关实体(如员工),而...

    hibernate one-to-one 一对一唯一外键关联映射_单向 and 双向

    在上面的配置中, `&lt;many-to-one&gt;` 标签指定了Person实体与IdCard实体之间的一对一唯一外键关联关系,其中unique="true"指定了多的一端的多重性为一。 Hibernate 一对一唯一外键关联映射的应用 在实际应用中,一对...

    Hibernate-one-to-many

    同时,`Account.hbm.xml`中的`many-to-one`元素将`column`属性设置为`FID`,表示通过`FID`字段关联到`User`实体。 #### 测试场景解释 在测试场景中,我们创建了一个`User`对象和一个`Account`对象,并在`User`对象...

    Hibernate Tutorial 04 (Many-to-one and One-to-one Association

    为了使用 `publisher` 属性,我们需要在 `Book` 类的 Hibernate 映射文件中添加 `&lt;many-to-one&gt;` 映射。这将在 `BOOK` 表中添加一个名为 `PUBLISHER_ID` 的列,并存储关联出版商的 ID。 ```xml &lt;!-- 其他属性的...

    hibernate学习5之one-to-many双向关联.docx

    在配置双向一对多关联时,我们通常在"多"一端(这里是`Student`)的集合属性上使用`&lt;many-to-one&gt;`标签,将`Classes`对象映射到数据库中的外键。同时,在"一"端(`Classes`)使用`&lt;set&gt;`标签,表示班级可以包含多个...

    Hibernate应用例子many-to-many

    本示例将详细讲解如何在Hibernate中实现多对多(many-to-many)的关系映射。 在数据库设计中,多对多关系是指两个实体之间存在多个关联,比如学生和课程的关系,一个学生可以选修多门课程,一门课程也可以被多个...

    Hibernate one-to-many-annotation

    在Hibernate中,`one-to-many`关系是常见的实体间关系之一,表示一个实体可以与多个其他实体相关联。本文将深入探讨`Hibernate one-to-many`注解的使用和实现细节。 ### 一、`@OneToMany`注解概述 `@OneToMany`...

    Hibernate one to many(many to one) 配置

    标题"Hibernate one to many(many to one) 配置"涉及到的是关系型数据库在Java中的持久化框架Hibernate中的两种关联映射关系:一对一(One-to-One)和多对一(Many-to-One)。在数据库设计中,这种关系很常见,例如...

    Hibernate实现many-to-many的映射关系

    3. 在对应的映射文件中,使用`&lt;set&gt;`和`&lt;one-to-many&gt;`或`&lt;many-to-one&gt;`元素配置映射关系。 4. 如有必要,可以考虑将多对多关系转换为一对多,以优化性能和操作性。 理解并熟练掌握这些概念和实践,将有助于在使用...

    many-to-one 配置详解

    many-to-one 配置详解 讲的很清楚 适合新手 值得下载

    hibernate many to one

    在Java的持久化框架Hibernate中,"Many-to-One"关系是一种常见的关联映射类型,它表示一个实体(类)可以与多个其他实体实例相关联。在这个主题中,我们将深入探讨Hibernate如何处理这种关系,以及如何在实际编程中...

    Hibernate集合关系映射及one-one,one-many,many-many示例(带注释)

    本程序包含: hibenate 上传图片,二进制数据,大文本,集合映射的多种关系,onetoone,ontomany,manytomany等关系详细代码示例以及注释,全部由本人测试通过,对理解hibernate配置有极大帮助。

    day36 07-Hibernate抓取策略:many-to-one上的抓取策略

    在提供的文件"hibernate_day03"中,可能包含相关的代码示例和更深入的解释,通过阅读和实践这些内容,你可以更好地掌握Hibernate的抓取策略,特别是对于"many-to-one"关系的应用。记住,理论知识固然重要,但实践...

    Hibernate之第3解之-hibernate_hibernate_many2one_1

    本篇将重点探讨Hibernate中的Many-to-One关系映射,帮助开发者更深入地理解和运用这一关键特性。 Many-to-One关系是现实世界中常见的关联类型,一个实体可能对应另一个实体的多个实例,例如,一个员工可以属于一个...

    hibernate 关联映射(一) many to one

    本文将深入探讨“Hibernate关联映射中的Many-to-One关系”。 Many-to-One关联是现实世界中常见的关系类型,比如一个学生可以对应多个课程,而一个课程可能被多个学生选修。在数据库中,这通常表现为一对多(One-to-...

Global site tag (gtag.js) - Google Analytics