lazy
=========================================================================
例子----------
数据库表
create table users(
id int primary key,
sname varchar2(30),
myclassid references class(id)
)
create table myclass(
id int primary key,
no varchar2(35)
)
注: 一个班级可以有多个学生, 每个学生都有一个班级 学生vs班级 many-to-one
users.hbm.cfg 摘要
<class name="com.chsoft.bean.Users" table="Users" schema="Test">
<id name="id" type="java.lang.Long">
<column name="ID" precision="4" scale="0" />
<generator class="sequence" />
</id>
<property name="sname" type="java.lang.String">
<column name="sname" length="20" />
</property>
<many-to-one name="myclass" column="myclassid" class="com.chsoft.bean.MyClass">
</many-to-one>
</class>
--------------------------------------------------------------
myclass.hbm.cfg摘要
<class name="com.chsoft.bean.MyClass" table="myclass" schema="Test">
<id name="id" type="java.lang.Long">
<column name="ID" precision="4" scale="0" />
<generator class="sequence" />
</id>
<property name="no" type="java.lang.String">
<column name="no" length="20" />
</property>
<set name="users">
<key>
<column name="myclassid" precision="4" scale="0"
not-null="true" />
</key>
<one-to-many class="com.chsoft.bean.Users" />
</set>
</class>
-------------------------------------------------------------------
备注:hibernate3 默认集合lazy=true , 关联对象lazy=“proxy” 都是使用延迟加载
根据数据库生成的bean
-------------------------------------------------------
Users|
------
public class Users extends ActionForm {
private Long id'
private MyClass myclass;
private String sname;
// Constructors
/** default constructor */
public Users() {
}
/** minimal constructor */
public Users(MyClass myclass, String sname) {
this.myclass= myclass;
this.sname = sname;
}
/** full constructor */
public Users(MyClass myclass, String sname) {
this.myclass= myclass;
this.sname = sname;
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public MyClass getMyClass() {
return this.myclass;
}
public void setMyClass(MyClass myclass) {
this.myclass= myclass;
}
public String getSname() {
return this.sname;
}
public void setSname(String sname) {
this.sname = sname;
}
}
-------------------------------------------------
MyClass 代码|
-------------
public class MyClass extends ActionForm {
private Long id;
private String no;
private Set users= new HashSet(0);
public MyClass() {
}
/** minimal constructor */
public MyClass(String no) {
this.classno = classno;
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getNo() {
return this.no;
}
public void setNo(String no) {
this.no = no;
}
public Set getUsers() {
return this.users;
}
public void setStudents(Set users) {
this.users= users;
}
}
--------------------------------------------------------
dao层代码摘要 在父类中封装了session
---------------------------------------------------------
public List showAll() throws Exception {
Criteria cr = this.getSession().createCriteria(Student.class);
return cr.list();
}
service层代码摘要
---------------------------------------------------------
public List showAll() throws Exception {
return userDao.showAll();
}
---------------------------------------------------------
页面代码
<c:forEach var="user" items="${users}" varStatus="index">
<tr>
<td align="center">
${index.index + 1 }
</td>
<td align="center">
${user.sname }
</td>
<td align="center">
<!--${user.myclass.no} 查询关联对象-->
<!--${user.myclass.id} 不查询关联对象-->
</td>
</tr>
</c:forEach>
这样在不需要使用关联的班级时 就不需要立即去数据库查询出关联的对象,减少不必要的数据操作,提高性能
分析:
当调用查询方法显示到jsp上时.当值显示users的信息时,所关联的 班级class信息就不会执行查询. (即lazy) ,当使用到users对象所关联的MyClass的属性时才会想数据库执行查询对应的信息. 使用默认若是访问关联对象的主键id 时 也不会产生查询.
这样就会节省很多不必要的查询,提高性能。
=============================================================================
inverse|
=============================================================================
inverse 是用来说明当关联关系(many-to-one)有时,关联的主键关系有谁来维护.
inverse = false或是说inverse=true对应的一方来维护
这里引用一位网友的回答。已经说的很清楚。因为没有看到作者名 所以略了.要是看到了别批我没注明引用。共同学习
------------------------------------------------------------------
inverse常用于一对多双向关联关系中。
以Student(学生)和Class(班级)为例,它们之间的关系为一对多的关系,即一个学生只能属于一个班级,一个班级可以包含多个学生。
学生类定义代码:
Class Student{
private int id;
private String name;
private Class class;
//省略getter()和setter()方法
}
班级类定义代码:
Class Class{
private int id;
private String name;
private Set students = new HashSet();
//省略getter()和setter()方法
}
Student类的映射文件:
<class name="Student" table="STUDENT">
<id name="id" type="int" column="ID">
<generator class="native" />
</id>
<property name="name" type="string" column="NAME" />
<many-to-one name="class" column="CLASS_ID" class="Class" cascade="save-update" />
</class>
Class类的映射文件:
<class name="Class" table="CLASS">
<id name="id" type="int" column="ID">
<generator class="native" />
</id>
<property name="name" type="string" column="NAME" />
<set name="students" table="STUDENT" cascade="save-update" inverse="false">
<key column="CLASS_ID" />
<one-to-many class="Student" />
</set>
</class>
希望你能对这两个映射文件所表达的数据库模式有正确的认识。即STUDENT表中存在一个名为CLASS_ID的字段,它和CLASS表中的ID字段是主外键关系。那个inverse属性就是用来规定是由谁(Student或Class)来维护这个主外键关系的。
inverse的默认值为false。
在处理逻辑代码中,如下:
Class c1 = new Class();
c1.setName("一班");
Student s1 = new Student();
Student s2 = new Student();
s1.setName("Jason");
s2.setName("Tom");
c1.getStudents().add(s1);
c2.getStudents().add(s2);
s1.setClass(c1);
s2.setClass(c1); //注释1
session.save(c1);
上面的代码会使Hibernate执行五条SQL语句,其中前三条是insert插入语句,后两条是update更新语句。插入就不用说了,那么为什么还要有更新语句呢?这是因为Class类映射文件的元素中指定了inverse="false",这就告之Hibernate:STUDENT表与CLASS表的主外键关系是由Class类来维护的。当执行save后,执行了三条insert语句,这三条语句中的后两条是插入到STUDENT表的,它们的CLASS_ID字段是通过s1.getClass().getID()取出的,假如我将上面“注释1”处修改为s2.setClass(c2);(c2是另一个Class对象,可能是持久化对象),这样,主外键关系不就乱了吗。为了保证主外键关系,Hibernate在这种情况下会再执行两条update语句来更改STUDENT表中两个新插入记录的CLASS_ID字段,当然,这时CLASS_ID字段的取值是从c1对象中直接取得,而不再是s1.getClass().getID()方式了。
如果我们将Class类映射文件的元素中的inverse属性修改为true,这就是告诉Hibernate:Class类不维护主外键关系了,这个任务就交给了Student类。于是,我们再执行上面的代码,Hibernate就会只执行三条insert语句,而不会执行任何update语句。因为Hibernate会通过Student类的s1.getClass().getID()和s2.getClass().getID()来确定CLASS_ID字段的值。
故,为了节省数据库资源,省却不必要的update语句,我们一般建议在一对多双向关联关系中,将一方的inverse属性设置为true,即将主外键的关系交由多方来维护。
打个比方:在一个公司中,是老板认识所有的员工容易,还是所有员工认识老板容易?
我是一个Hibernate的初学者,
============================================================================
再次感谢无私奉献的人们.加油
分享到:
相关推荐
<set name="addresses" inverse="true" lazy="true"> ``` 这样,当查询`User`对象时,`Address`集合不会立即加载,只有在调用该集合时才会发起数据库请求。 接下来,在Flex客户端,我们需要使用Gilead的...
根据提供的文件信息,我们可以深入探讨Hibernate框架中的几个关键概念,特别是`fetch`, `lazy`, `cascade`, 和 `inverse`关键字的使用与理解。这四个概念在处理对象关系映射(ORM)时非常重要,尤其是在Java环境下...
为了确保Hibernate能够正确地识别和处理Java对象,开发者需要重写`equals()`和`hashCode()`方法,以便Hibernate能够根据对象的业务逻辑判断对象是否相等。 #### 多对一与一对多实体映射 在关系数据库中,多对一和一...
**Hibernate 结构框架详解** Hibernate 是一款流行的 Java...了解这些核心概念和类的作用,可以帮助开发者更好地利用 Hibernate 进行数据库操作,实现SDO(Service Data Object)和DAS(Data Access Service)等功能。
- Inverse和Cascade: 关联关系中的级联操作。 - 延迟加载(LazyLoading): 减少内存占用和提高性能的技术。 - **事务管理**: - **基于JDBC的事务管理**: - 直接使用JDBC进行事务控制。 - **基于JTA的事务管理**: ...
<set name="addresses" table="address" lazy="true" inverse="true"> ``` **工作原理:** 当执行如下代码时: ```java User user = (User) session.load(User.class, "1"); Collection addresses = user....
在 Java 代码中,你可以创建 `User` 和 `Role` 实例,并通过 `add` 方法添加到对方的集合中,Hibernate 会自动处理中间表的插入和更新。 ```java User user = new User(); user.setUsername("testUser"); Role ...
本文将深入探讨Hibernate框架下“多对一”和“一对多”的关联关系,并通过一个具体示例来阐述其操作流程与实现细节。 ### Hibernate中的“多对一”和“一对多” 在数据库设计中,“多对一”(Many-to-One)和“一...
<set name="orders" table="ORDER" inverse="true" lazy="true"> ``` 或者使用注解: ```java @Entity public class User { @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) @org.hibernate....
在一对多关联中,你可能会遇到懒加载(lazy loading)和立即加载(eager loading)的问题,以及如何处理级联操作。 在`OneToMany_1`这个文件中,应该包含了具体的源代码示例,包括实体类、映射文件和测试类。通过...
@hibernate.bag(inverse=true, lazy=true) private Set<Comment> comments; ``` #### 三、@hibernate Tag for Field Level 在字段级别的@hibernate Tag用于定义更细粒度的属性。 ##### 3.1 @hibernate.cache (0.....
<set name="addresses" table="address" lazy="true" inverse="true"> </hibernate-mapping> ``` 当执行`session.load(User.class, "1")`后,即使调用了`getAddresses()`方法,Hibernate也不会立即查询...
描述提到这是一个已经成功运行的项目,目的是为了便于学习者更好地理解和实践Hibernate双向一对多的关系映射。通过实际的项目案例,学习者可以直观地看到配置、实体定义、DAO操作以及Service层的实现,从而加深对这...
- **数据访问**:讨论PO(Persistent Object)和VO(Value Object)的区别,以及unsaved-value属性的作用,深入解析Inverse和Cascade机制,解释延迟加载(Lazy Loading)的原理和应用场景。 - **事务管理**:分析...
11.1.2 Java时间和日期类型的Hibernate映射类型 11.1.3 Java大对象类型的Hibernate映射类型 11.1.4 JDK自带的个别Java类的Hibernate映射类型 11.1.5 使用Hibernate内置映射类型 11.2 客户化映射类型 ...
在使用集合映射时,需要注意懒加载(lazy loading)和批处理(batch-size)的设置,以优化性能。懒加载避免了在不需要整个集合时加载所有数据,而批处理则可以减少数据库访问次数。 ### 7. 总结 理解并熟练应用...