(day3)Hibernate知识培训[many-tomany(以学生选课为例)]

. many-tomany(以学生选课为例)        

1.Student.hbm.xml文件的设置

<set name="students" table="ying_enrollment" cascade="none"><!--cascade 设置为none,为了减少update更新冗余--!>

<key column="fcid"></key>

<many-to-many class="Student" column="fsid"/>

<!-- table ying_enrollment 中间表,体现多2多关系 -->

</set>

2.Course.hbm.xml文件的设置

<set name="courses" table="ying_enrollment" cascade="save-update" inverse="true"

lazy="false"><!-- lazy表示是否延迟加载set对象,false使Session关闭后仍然可用 -->

<key column="fsid"></key>

<many-to-many class="Course" column="fcid"/>

<!-- table ying_enrollment 中间表,体现多2多关系 -->

</set>

Student实体类中要设置StudentCourse的关联:

public void registerCourse(Course c) {

courses.add(c);

c.getStudents().add(this);

}

3.: hibernate的实现方式是通过中间表(ying_enrollment),间接实现了多对多关系,实际上也是将多对多拆分

成两个双向的一对多关系。

Hibernate知识点小记

1.cascade

cascade属性是设置级联操作的也就是在操作一端的数据如果影响到多端数据时会进行级联操作,一对一的时候直接写在标签上,其他的要写在set标签上

cascade="none|save-update|all|all-delete-orphan"

none 就是不使用级联操作,默认级联是none

save-update 也就是只有对象保存操作(持久化操作)或者是持久化对象的更新操作,才会级联操作关联对象(子对象)。

all-delete-orphan,在多端进行删除操作时,会再多端表中留下null空纪录,设置了级联操作为delete之会将表中表示关联的外键id置成null

不会将这条纪录也删除掉,而把级联设置成delete-orphan就不会留有空纪录,而是级联的把相关纪录删除掉。

2.inverse

inverse="true"就是在设置如果在内存中的修改或添加了这个集合中的某一个或某几个对象他不会将全部集合的信息同步到数据库,而是只将集合中被修改的对象重新同步到数据库

3.lazy

lazy=“true”

延迟加载,所谓的延迟加载,就是对一端的集合属性的加载策略,就是在不使用到集合中的对象的数据就不会真正的加载集合中的对象数据,而是家在一个代理对象就相当于的一个空的容器。这也就是会出现LazyInitializationException异常,也就是没有初始化这个代理的集合对象,在事先查询到了集合中的对象就会初始化这个对象,如果Session没有关闭就会在查询加载集合中的对象信息,如果提前关闭了Session,当使用集合中的对象信息时就会有这个异常。

4.fetch

fetch=“join”,这就是使用了预先抓取策略,也就是针对关联的对象的加载策略,在使用到关联对象的信息时会再发送sql语句,如果不使用fetch=“join”,就会不使用表连接而是先查出一端的关联id再一条一条的发送sql语句查询到关联对象信息,使用了fetch=“join”就会使用表连接将关联对象信息直接查寻出来的。fetch=“lazy”这个是默认的设置。

. inherit_mapping

建表策略(Account CheckAccount DebitAccount 类为例)

1)只为具体类建表只为具体类建表,使用于不使用多态的情况下,具体类之间没有继承关系时适用需要针对每个类写映射配置文件,就和普通的单表映射的xml文件相同。也可以使用一个xml文件来进行映射,可以通过写union-subclass标签来表现其关系这里不能使用id生成策略中的native,而是要指定特定的生成策略。

例:

<union-subclass name="CheckAccount"

table="t_check_account"><!-- 只为具体类建表 -->

<property name="overdraft"></property>

</union-subclass>

<union-subclass name="DebitAccount"

table="t_debit_account"><!-- 只为具体类建表 -->

<property name="currency"></property>

</union-subclass>

2)每个类建一个表每个类建一个表,可以有效减少数据的冗余,减少字段,查询效率不很高。正对每个类建一个表,只要写一个配置文件来进行类的映射即可映射文件中的子类可以使用join-subclass标签来表示,并且引用父类的主键作为共享主键,就是不需要指定id生成策略

例:

<joined-subclass name="CheckAccount"

table="ying_check_account"><!-- 每一个类建一个表 -->

<key column="faid"></key>

<property name="overdraft"></property>

</joined-subclass>

<joined-subclass name="DebitAccount"

table="ying_debit_account"><!-- 每一个类建一个表 -->

<key column="faid"/>

<property name="currency"></property>

</joined-subclass>

3)所有类建一个表所有类只建一个表,查寻效率比较高,但是会产生很多空间浪费,当子类中有非空约束,就不大适用了,这是对于子类可以使用subclass标签表示。

:

<subclass name="CheckAccount"

discriminator-value="c">

<property name="overdraft"></property>

</subclass>

<subclass name="DebitAccount"

discriminator-value="d">

<property name="currency"></property>

</subclass>

: 不考虑多态时,最好是用只针对具体类建表(2个表),而考虑多态时尽量使用所有类建一个表,

只有当子类中的属性过多是才考虑每个类建一个表的策略。

4)三种策略的比较:(详见孙卫琴主编的精通Hibernate一书P424)如果不需要支持多态查询和多态关联,可以采用每个具体类对应一个表如果需要持多态查询和多态关联,并且子类包含的属性很多,可以采用所有类对应一个表如果需要持多态查询和多态关联,并且子类包含的属性很多,可以采用每个类对应一个表

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值