看下面的例子
user和班级,多对一得关系。
目标:希望查询学生的时候,知道学生所在班级信息
public class User {
private Long userId;
private String userName;
private GradeClass gradeClass;
...//省略get和set方法
User.hbm.xml
<hibernate-mapping>
<class name="com.supben.pojo.User" table="User">
<id name="userId" type="java.lang.Long">
<column length="20" name="userId" />
<generator class="identity"></generator>
</id>
<property name="userName" type="java.lang.String">
<column name="userName" />
</property>
<!--column="gradeClassId" 表示的是user表中和班级表关联字段gradeClassId -->
<many-to-one name="gradeClass" column="gradeClassId" class="com.supben.pojo.GradeClass" />
</class>
</hibernate-mapping>
GradeClass.hbm.xml,和平时的配置没有任何的不同!
<hibernate-mapping>
<class name="com.supben.pojo.GradeClass" table="gradeclass">
<id name="gradeClassId" type="java.lang.Long">
<column length="20" name="gradeClassId" />
<generator class="identity"></generator>
</id>
<property name="gradeClassName" type="java.lang.String">
<column name="gradeClassName" />
</property>
</class>
测试代码
public void testFind() {
List<User> userList = userService.findAll();
assertEquals(2, userList.size());
System.out.println("*************************************");
System.out.println(userList.get(0).getGradeClass().getGradeClassName());
...//(省略dao和service中的查询方法)
}
Hibernate: select this_.userId as userId1_0_, this_.userName as userName1_0_, this_.gradeClassId as gradeCla3_1_0_ from User this_
*************************************
1084 [main] ERROR org.hibernate.LazyInitializationException -
could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize
proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:86)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:140)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
at com.supben.pojo.GradeClass_$$_javassist_1.getGradeClassName(GradeClass_$$_javassist_1.java)
at com.supben.service.UserServiceTest.testFind(UserServiceTest.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
可以看到hibernate 3 many-to-one 默认是延迟加载的,出现了异常:不能初始化代理对象,session超时。
把配置文件改成lazy="false"呢,即这样配置
<many-to-one name="gradeClass" column="gradeClassId" class="com.supben.pojo.GradeClass" lazy="false" />
运行结果一切正常,在拿到user对象之后,立即发出2条sql去拿到班级对象。
Hibernate: select this_.userId as userId1_0_, this_.userName as userName1_0_, this_.gradeClassId as gradeCla3_1_0_ from User this_
Hibernate: select gradeclass0_.gradeClassId as gradeCla1_0_0_, gradeclass0_.gradeClassName as gradeCla2_0_0_ from gradeclass gradeclass0_ where gradeclass0_.gradeClassId=?
Hibernate: select gradeclass0_.gradeClassId as gradeCla1_0_0_, gradeclass0_.gradeClassName as gradeCla2_0_0_ from gradeclass gradeclass0_ where gradeclass0_.gradeClassId=?
*************************************
101
优化:在配置文件里加上fetch="join"在运行,可以看到控制台的输出为:
Hibernate: select this_.userId as userId1_1_, this_.userName as userName1_1_, this_.gradeClassId as gradeCla3_1_1_, gradeclass2_.gradeClassId as gradeCla1_0_0_, gradeclass2_.gradeClassName as gradeCla2_0_0_ from User this_ left outer join gradeclass gradeclass2_ on this_.gradeClassId=gradeclass2_.gradeClassId
*************************************
101
只发出了一条sql就获得了所有的结果。这是因为hibernate默认是用fetch="select"的方式,即根据gradeClassId去select。改成了join,就会一次性查出
分享到:
相关推荐
在Hibernate中,可以通过 `<many-to-one>` 或者 `<one-to-many>` 标签中的 `cascade` 属性来指定这种行为。 #### 代码示例解析 在提供的代码示例中,`<many-to-one>` 标签中包含了 `cascade` 属性的注释示例,但是...
"Hibernate one-to-many / many-to-one关系映射"是两个基本的关系类型,用于表示实体间的关联。在这个主题中,我们将深入探讨这两种关系映射的原理、配置和实际应用。 一、一对一(one-to-one)与一对多(one-to-...
本话题主要探讨两种基本的关系映射类型:many-to-one(多对一)和one-to-many(一对多)。这两种关系映射是数据库中常见的关联类型,理解和掌握它们对于开发高质量的Java应用至关重要。 1. many-to-one关系 many-to...
在Hibernate中,一对一唯一外键关联映射可以通过 `<many-to-one>` 标签来配置。例如,以下是Person实体与IdCard实体的一对一唯一外键关联映射配置: ```xml <many-to-one name="idCard" column="card_id...
在Hibernate中,`one-to-many`关系是常见的实体间关系之一,表示一个实体可以与多个其他实体相关联。本文将深入探讨`Hibernate one-to-many`注解的使用和实现细节。 ### 一、`@OneToMany`注解概述 `@OneToMany`...
对于`Department`,映射文件中会有一个`<class>`标签,其中包含`<set>`标签来定义员工集合,并且使用`<many-to-many>`或`<one-to-many>`标签来映射与`Employee`的关系。对于`Employee`,我们使用`<class>`标签,并在...
而`Classes.hbm.xml`则使用了`<set>`和`<one-to-many>`元素,表示班级对象包含一个学生集合,且每个学生都有对应的`id`。 在处理这种关联关系时,需要注意的是效率问题。由于Hibernate默认会在"一"端更新关联关系,...
Hibernate中many-to-one关系的编写_远航的水手
Hibernate中many-to-one关系的编写_远航的水手.htm
在 `Book` 类中,我们可以添加一个指向 `Author` 的属性,并在映射文件中使用 `<one-to-one>` 标签。 ```xml <!-- 其他属性的映射 --> <one-to-one name="author" class="Author" column="AUTHOR_ID" cascade=...
本文将深入探讨Hibernate中一对多(One-to-Many)关系的处理方式,特别是通过外键映射和inverse属性的应用场景。 #### 一对多关系概念 一对多关系在数据库设计中非常常见,它指的是一个实体可以与多个其他实体关联...
many-to-one 配置详解 讲的很清楚 适合新手 值得下载
本示例将详细讲解如何在Hibernate中实现多对多(many-to-many)的关系映射。 在数据库设计中,多对多关系是指两个实体之间存在多个关联,比如学生和课程的关系,一个学生可以选修多门课程,一门课程也可以被多个...
3. 在对应的映射文件中,使用`<set>`和`<one-to-many>`或`<many-to-one>`元素配置映射关系。 4. 如有必要,可以考虑将多对多关系转换为一对多,以优化性能和操作性。 理解并熟练掌握这些概念和实践,将有助于在使用...
本文主要关注Hibernate中的一个核心概念——一对一(One-to-One)、一对多(One-to-Many)和多对一(Many-to-One)关联映射,特别是关于“一到多”单向和双向关联映射的配置心得。 首先,让我们了解“一到多”关联...
标题"Hibernate one to many(many to one) 配置"涉及到的是关系型数据库在Java中的持久化框架Hibernate中的两种关联映射关系:一对一(One-to-One)和多对一(Many-to-One)。在数据库设计中,这种关系很常见,例如...
依旧无需特殊配置,除非你需要定义反向关系(one-to-many)。 ### 3. 关联的生命周期管理 在`CascadeType.ALL`中,`Cascade`属性定义了对关联对象的操作应该如何传播。这里包括了对`Class`的CRUD操作。例如,当...
今天我们要讨论的是Hibernate框架中的一个关键概念——抓取策略,特别是针对"many-to-one"关系的抓取策略。这篇博客将深入剖析这个主题,帮助你更好地理解和应用Hibernate。 Hibernate是Java领域中最流行的对象关系...
在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者用面向对象的方式处理...在后续的学习中,你还可以探索其他类型的关联,如One-to-One、Many-to-Many等,进一步提升你的Hibernate技能。