`
maomaolingyu
  • 浏览: 5799 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

hibernate 之 lazy 和 inverse

阅读更多
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(&quot;一班&quot;);
Student s1 = new Student();
Student s2 = new Student();
s1.setName(&quot;Jason&quot;);
s2.setName(&quot;Tom&quot;);
c1.getStudents().add(s1);
c2.getStudents().add(s2);
s1.setClass(c1);
s2.setClass(c1);   //注释1
session.save(c1);

上面的代码会使Hibernate执行五条SQL语句,其中前三条是insert插入语句,后两条是update更新语句。插入就不用说了,那么为什么还要有更新语句呢?这是因为Class类映射文件的元素中指定了inverse=&quot;false&quot;,这就告之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的初学者,

============================================================================

再次感谢无私奉献的人们.加油


分享到:
评论

相关推荐

    Hibernate中Cascade和inverse的区别

    Hibernate中Cascade和inverse的区别,讲解的很详细

    hibernate

    Hibernate fetch lazy cascade inverse 关键字

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     11.1.2 Java时间和日期类型的Hibernate映射类型  11.1.3 Java大对象类型的Hibernate映射类型  11.1.4 JDK自带的个别Java类的Hibernate映射类型  11.1.5 使用Hibernate内置映射类型  11.2 客户化映射类型  ...

    hibernate总结

    持久化类的对象,在hibernate应用中可以处于三种状态(根据对象和session之间的关系进行划分): 1. 临时态,瞬态:特点: a) 在数据库中没有记录和它对应 b) 和session没有任何关系 c) New 出来的对象,都处于临时...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     11.1.2 Java时间和日期类型的Hibernate映射类型  11.1.3 Java大对象类型的Hibernate映射类型  11.1.4 JDK自带的个别Java类的Hibernate映射类型  11.1.5 使用Hibernate内置映射类型  11.2 客户化映射类型  ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     11.1.2 Java时间和日期类型的Hibernate映射类型  11.1.3 Java大对象类型的Hibernate映射类型  11.1.4 JDK自带的个别Java类的Hibernate映射类型  11.1.5 使用Hibernate内置映射类型  11.2 客户化映射类型  ...

    Hibernate注释大全收藏

    @Basic(fetch = FetchType.LAZY) String getDetailedComment() { ... } // persistent property @Temporal(TemporalType.TIME) java.util.Date getDepartureTime() { ... } // persistent property @Enumerated(Enum...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     11.1.2 Java时间和日期类型的Hibernate映射类型  11.1.3 Java大对象类型的Hibernate映射类型  11.1.4 JDK自带的个别Java类的Hibernate映射类型  11.1.5 使用Hibernate内置映射类型  11.2 客户化映射类型  ...

    Hibernate Reference Documentation3.1

    Bags and lists are the most efficient inverse collections 19.5.4. One shot delete 19.6. Monitoring performance 19.6.1. Monitoring a SessionFactory 19.6.2. Metrics 20. Toolset Guide 20.1. Automatic ...

    Hibernate_Annotation关联映射

    和其它许多批注一样,在多对多关联中很多值是自动生成,党双向多对多关联中没有定义任何物理映射时,Hibernate根据以下规则生成相应的值,关联表名:主表表名+下划线+从表表名,关联到主表的外键名:主表名+下划线+...

    Hibernate开发指南

    Inverse 和 Cascade ......................................................................... 61 延迟加载(Lazy Loading)............................................................61 事务管理 ...........

    hibernate3.6 文档(pdf 格式)

    1.1. Part 1 - The first Hibernate Application ................................................................ 1 1.1.1. Setup .............................................................................

    JAVA自学之路

    7:XML (XML/XSL、XSLT/DTD、SCHEMA等基础的概念、关于Java的编程可以暂时扔在一边) 8:Hibernate OR Mapping原理 Hibernate基础开发步骤 ...inverse lazy cascade 继承关系映射 HQL 性能优化 一级

Global site tag (gtag.js) - Google Analytics