兔八哥笔记15(1):Hibernate中的父子关系

来源:互联网 发布:追星软件有哪些 编辑:程序博客网 时间:2024/04/29 04:40

兔八哥笔记15Hibernate中的父子关系

          邮箱:ltf_ty@163.net

 

       本文翻译自Hibernate帮助文档的第九章。

Hibernate的新用户用Hibernate做的第一件事情很可能就是建立一个父子关系的数据模型。要达到这个目的,有2种途径:由于有不同的情况,最方便(特别是对于一个Hibernate的新用户来说)的途径是同时建立2个实体,一个是Parent,另一个是Child,然后建立一个从ParentChild<one-to-many>关联。另外一个途径是生命Child作为Parent<composite-element>Now, it turns out that default semantics of a one to many association (in Hibernate) are much less close to the usual semantics of a parent / child relationship than those of a composite element mapping.(这句没太读明白)。下面我们将向你展示怎样使用bidirectional one to many association with cascades去建立一个优雅且有效率的父子关系的模型,一点都不难!

 

9.1 关于集合的小结(A note about collections

       Hibernate集合被认为是实体自己的一个逻辑部分,而不是被包含的实体。这个区别是至关重要的!

       当我们从一个集合中增加或删除一个对象时,集合所有者的版本号将会增加。

       如果从集合中被删除的对象是一个值类型的实例(eg, a composite element),对象将不再是持久的,它的状态将从数据库中完全删除。同样,向集合中增加一个值类型的实例时,将会使它的状态立刻被持久化。

       另一方面,如果一个实体从一个集合(a one-to-many or many-to-many association),中被removed,默认情况下,关联的实体将不被删除(deleted)。这个行为同下面的说法是完全一致的:其他实体的内部状态的改变不应该引起相关联的实体的消失(vanish)!同样,向集合中增加一个实体,在默认情况下,不会引起实体被持久化。

       所以,向集合中增加一个实体时,仅仅是创建了一个两个实体之间的连接(link),而删除时,也仅仅删除了连接(link),这个规则适合各种各样的(all sorts of)情况。但也有根本不适合的情况:在父子关系中,Child的生命被绑定到Parent对象的生命期(lifecycle)中。

      

9.2 双向的one-to-manyBidirectional one to many

       假设我们有一个简单的从ParentChild对象的<one-to-many>关联:

<set name="children">

      <key column="parent_id"/>

      <one-to-many class="Child"/>

</set>

    如果我们要执行下面的代码:

Parent p = .....;

Child c = new Child();

p.getChildren().add(c);

session.save(c);

session.flush();

Hibernate将转换成2SQL语句:

²        一条为创建Childinsert语句

²        一条创建ParentChild的关系的update语句

这样做不仅效率低下,而且违反了parent_id列的NOT NULL约束。

下面的动机是:从ParentChild的连接(外键:parent_id)没有被作为Child的状态的部分被考虑,所以在Insert中没有被创建。所以,我们将建立Child映射部分的连接:

<many-to-one name="parent" column="parent_id" not-null="true"/>

       我们也需要为Child类增加parent属性。

       现在Child实体被作为连接的状态被管理,我们使用inverse告诉集合不要去更改连接。

     <set name="children" inverse="true">

          <key column="parent_id"/>

        <one-to-many class="Child"/>

   </set>

   下面的代码将添加一个新的Child:

Parent p = (Parent) session.load(Parent.class, pid);

Child c = new Child();

c.setParent(p);

p.getChildren().add(c);

session.save(c);

session.flush();

现在,只有一个Insert语句被执行!

       下面我们为Parent添加一个addChild()方法:

public void addChild(Child c) {

    c.setParent(this);

    children.add(c);

}

现在,添加一个Child的代码应该看起来像这样:

Parent p = (Parent) session.load(Parent.class, pid);

Child c = new Child();

p.addChild(c);

session.save(c);

session.flush();

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 我朋友借的网贷光给我打电话怎么办 电脑上的文件变成了图片查看怎么办 外卖店打印机纸卡住打不开了怎么办 微信撤回图片留下一堆代码怎么办 拼多多砍价免费拿砍不到0元怎么办 一岁三个月宝宝老足拉肚子怎么办丶 想打好关系送礼发红包不敢收怎么办 我在相亲市场太受欢迎了怎么办小说 有人报警说我诈骗警察说立案怎么办 微信账号长时间未登录不想要怎么办 手机号注销了百度云登录不了怎么办 申请百度云账号的手机不用了怎么办 新注册的微信号显示账号异常怎么办 注册公众号说邮箱被占用了怎么办 向钱贷登录手机号换了怎么办 qq号绑定的手机号码换了怎么办 用手机号注册的支付宝换号了怎么办 支付宝转的账户手机号消号了怎么办 激活微信账号手机号写错了怎么办 大学试卷没有写名字和考号怎么办 公司被注销了公众号还想要怎么办 公司认证的公众号公司注销了怎么办 信而富注册手机号码不用了怎么办 信而富本时段额度已放完怎么办 知道qq号密码账号忘了怎么办 扣扣绑定的手机号被别人用了怎么办 我的手机号被别人绑定了快手怎么办 微信密码忘记了没绑定手机号怎么办 扣扣绑定银行卡忘记密码了怎么办 扣扣忘记密码了又换手机号了怎么办 微信订阅号里有删除后的信息怎么办 申请微信公众号邮箱已被占用怎么办 公众号验证没有对公账户怎么办 qq密码忘记了怎么办手机绑定没有 我的扣扣怎么申诉都找不回来怎么办 装修装的不好又没有签合同怎么办 日本免税的零食不小心拆了怎么办 闲鱼同意买家退货了买家不退怎么办 手机里淘宝钱付了不发货怎么办 百度云下载手机储存空间不足怎么办 苹果8的照片储存空间满了怎么办