hibernate对象关系实现(一)一对多

hibernate是对jdk一个封装工具,实现对象和数据库之间数据映射。使用时涉及到四个问题:a.对象之间的关系在类中的体现;b,对象关系对应的数据库中表之间体现;c.实现a,b在hibernate的配置,d.对象之间获取保存更新删除的差异

一:1-n/n-1(单向的一对多/多对一),1 <-> n (双向一对多即双向多对一).

单向:只能从特定的一方联系到另一方,类中的体现是一个对象有另一个对象(或者是对象数组)的引用做属性;

双向:对象之 间都有对方的引用;

一对多:一个对象关联多个对象

1.单向n-1:以多个订单对应一个客户为例

a.仅是多的一方订单类中引用客户对象:

        

                 (客户类)                                               (订单类):引用属性customer

b.数据库中,多的对应的订单表中拥有一的客户表主键做外键关联:

 

c.需要在多的订单类.hbm.xml中除一般的映射额外添加<manytoone>配置:

   客户类映射配置:

                                        

   订单类,映射配置:

   注意:引用属性customer对应的配置是<many-to-one> 中的配置;

            class的值:一的一端的类;

             colum的值:是客户表主键所对应的在订单表中外键的名称(可随意取);其值也将客户和订单联系起来

   hibernate.cfg.xml配置:

d.测试:省略session的获取提交关闭:

    or    

 执行效果:

 保存:先客户后订单将执行三条插入语句;

          先订单后客户将执行三条插入后再执行两条更新语句;因为订单的外键需要客户主键值,刚开始订单插入没有外键值,后面得外键值再更新。

 获取:

       

        默认情况下,获取订单对象时只发送查询订单的sql不会同时查询出关联的客户对象,

        

        只有当使用到订单中的客户对象时才去发送查询客户数据;实际上在获取订单对象时,内部关联的客户对象是一个代理对象,当使用时才去初始化数据(发送查询语句),如         果session关闭可能出现懒加载异常

 更新:

       

         执行的是查询查询再更新;(不需要添加更新操作,因为commit()前会自动检查持久对象是否需要更新)

  删除:

         

           默认情况库中主键有外键的引用不能执行删除。

2.双向n-1也是双向一对多:同样是客户和订单关系。多个订单对应一个客户。(突然想到单向一对多怎么弄)

a.双向即双方互相引用,特别之处是一的一方即客户类中有个集合属性引用多个订单对象;而订单类中只是引用客户对象做属性;

注意:一个是接口声明;一个初始化属性

b.数据库方面和上面说过的单向多对一的一样,即客户表的主键做订单的外键。

c.配置方面除了和单向多对一的方式相同外,还有配置一对多的映射配置。

c.1

name:属性名; table:属性对应的表名; column:"表中的外键名"; class:表对应的类

c.2:set元素中添加inverse=true属性;

通过inverse属性配置,让一的一方即客户方放弃对主键所对应的外键数据的维护;

d.测试:

   :记得添加customer对oreder的引用对象;

    保存:在c.1配置下

          先客户后订单将执行三条插入,两条更新语句;因为是双向维护的,可以看成是两个独立配置在维护数据。客户数据插入后,客户方去更新订单外键信息。

          先订单后客户将执行三条插入后再执行四条更新语句;因为订单的外键需要客户主键值,刚开始订单插入没有外键值,后面得外键值再更新。另外一的一方也去更新外键。

         

           c.2配置下:set元素中配置inverse=true;

           一的一方放弃对应的外键维护,即只由多的一方(订单类)来维护外键值,也是推荐使用的,因为一的一方不知道多的一方是否已经获取外键值总是去更新,而多的一方获           取到外键值后就不会再多余的更新操作了。

          保存的先后顺序和单向的一样。

之后的都是在c2配置下:

     获取:从订单对客户的获取和单向一样;(其实也就是每份配置决定获取的方式:)下面是客户中获取订单:

   

        因为也是延长加载,也可能出现懒加载异常。只有使用到集合的元素时才会进行初始化,即查询数据。可能在获取元素个数的时候,只是count语句,不初始化数据。

      更新:没什么特别的:

      删除:不能删除客户对象,因为有外键约束。

补充:set中的属性 inverse ,cascade,order-by

        inverse:反转的意思,默认为false;等于true表示外键值由多的一方维护。

        cascade:级联操作:(实际开发不建议使用)

                                  为delete时,删除客户就能把对应的订单全部删除;

                                  为delete-orphon时,清空客户中的集合对象时,就删除对应的订单,但客户数据仍然不变;

                                  为save-update时,只保存客户对象,将自动把对应的订单对象也保存;

       order-by:按字段进行排序:在查询对象集合集合时,会按字段进行排序查询;

      

           

           

          

  

原文地址:https://www.cnblogs.com/straybirds/p/5150043.html