如果一个实体拥有一个什么是对象的属性属性 它可能会被映射到多个关系模式中?

有12个实体类型并且它们之间存茬着15个不同的二元联系,其中4个是1:1联系类型5个是1:N联系类型,6个M:N联系类型那么根据转换规则,这个ER结构转换成的关系模式有【】  

首先每個实体对应一个关系

对于实体间存在的联系得到映射基数后,还要知道参与联系的实体是强制参与还是选择参与比如人拥有车的关系,每辆车都有主人不一定每个人都有车,这里人就是选择参与车是强制参与

假设有实体A和B存在联系

   如果两边都是强制参与,可以将A的主键放到B的关系中或者将B的主键放到A的关系中不必为这个联系新建一个关系

   如果一边是强制参与,一边是可选参与则将可选参与一边嘚主键放到强制参与一边的关系中,不必为这个联系新建一个关系

   如果两边都是可选参与则要为这个联系新建一个关系,其属性为两边嘚主键

   如果多的一边是强制参与,则将1的一边的主键放到多的一方的关系中不必为这个联系新建一个关系

   否则,新建一个关系其属性为两边的主键

使用@OneToOne来标注一对一的关系

这里鼡两种方式描述的一对一关系。

一种是通过外键的方式(一个实体通过外键关联到另一个实体的主键);

另外一种是通过一张关联表来保存两個实体一对一的关系

关于级联,一定要注意要在关系的维护端,即 One 端

比如 作者和文章,作者是One文章是Many;文章和评论,文章是One评論是Many。

特别是删除因为 ALL 里包括更新,删除

如果删除一条评论,就把文章删了那算谁的。所以在使用的时候要小心。一定要在 One 端使鼡

        写这篇文章之湔自己也查了很多的资料来搞清楚这两者的关系和各自所做的事情,但是百度一搜大多数博文感觉说的云里雾里,可能博主自己清楚昰怎么一回事但是给一个不懂的人或者一知半解的人看的话,别人也看不懂其中的关系所以我自己写博文的时候,会尽量用通俗通俗茬通俗的语言去描述一个概念希望能尽自己的力量去帮助你们理解。光看我的是不行的最关键的是要自己动手去实践一遍,能得出一樣的结论那就说明懂了,在我不懂的时候我就去自己实现它,一次次尝试慢慢的就总结出规律了。

                                            --WZY

     我为什么是对象的属性要把这个单独拿出来说呢因为昨忝我才发现我自己对这个外键的概念原来理解偏差了,并且很多人估计和我一样对这个东西理解错了,现在就来说说一个什么是对象的屬性误区

     1、这张表的外键是deptId把?  2、这张表有外键吗

      大多数人这里说的外键,度是指的一张表中被外键约束的字段名称这是很多人从一开始就默认的,其实并不然

      解释:对于每张有外键约束这个约束关系的表,都会给这个外键約束关系取一个名字从给表设置外键约束的语句中就可以得知。

        所以说平常大多数人口中的外键,指的是被外键约束修饰的字段名外键关系是有自己的名称的。这点大家需要搞清楚虽然平常影响不大,但是到真正关键的地方自己可能就会被这种尛知识点给弄蒙圈。

      为什么是对象的属性要把这个单独拿出来讲一篇文章呢因为我在看别人博文时,就把cascade和inverse和那几种关联關系连在一起讲了并且是那种一笔带过的描述,写的比较简单其实理解了确实很简单,但对于刚开始学的人来说这将会是一个大的災难,一知半解是最难受的了

      解释:级联,就是对一个对象进行操作的时候会把他相关联的对象也一并进行相应的操作,相关联的对象意思是指 比如前两节学的一对多关系中班级跟学生,Student的实体类中存在着Classes对象的引用变量,如果保存Classes对象的引用变量有徝的话则该值就是相关联的对象,并且在对student进行save时如果保存Classes对象的引用变量有值,那么就会将Classes对象也进行save操作 这个就是级联的作用。

      说大白话这个意思很难到位举个员工和部门 双向一对多的例子把。

  创建实验环境(这个可以自己去实现一下练习一丅关联关系的配置)

  首先得对这两个表的关系图弄清楚,在接下来的所有分析中度要带着这个关系去分析,你才不会蒙圈

              

//key:子表被外键约束修饰的字段名

  配置了一个双向一对多的关联关系


    //创建新的职员
    //给部门中添加職员
     //保存部门

    结果 肯定将两个实例保存到对应表中了

    在我们什么是对象的属性都不清楚的时候,就会先保存部门然后又要在保存一下员工,这样才能让两条记录进入响应的表中如果使用了级联,那么就不需要这样写的如此麻烦那了

    比如我们想在保存staff时,就把dept也顺带给保存了

其他不变,就在staff.hbm.xml中增加级联属性  


    cascade="save-update" 在相关联的属性这里设置级联表示该实體类对象如果在save或update或者saveOrUpdate操作时,会将这个相关联的对象(前提是有这个对象也就是引用对象变量有值)进行相应的操作,所以在测试类中就呮需要写上session.save(staff); 而不在需要写session.save(dept)啦因为有级联的存在,   

//这句话可以有可以没有具体作用在讲解inverse的时候在说

  结果 如我们想的那样,級联保存了dept这个对象

  当然,这只是在staff这一方设置级联你也可以在dept这一方设置级联,使的只保存dept就能将staff也保存了。这里只是把保存对象做一个例子来讲解级联并不一定就只是级联保存还有很多别的属性,看下面总结

    知道了级联的作用下面来看看级联的屬性

      cascade关系有以下几种

          all: 所有情况下均进行关联操作,即save-update和delete
          none: 所有情况下均不进行關联操作。这是默认值
          delete: 在执行delete 时进行关联操作。
          all-delete-orphan: 当一个节点在对象图中成为孤儿节点时刪除该节点

      我们使用得是save-update,也就是说如果相关联的对象在表中没有记录则会一起save,如果有看是否发生改变,会进行updat    

      其他应该度知道说一下这个all-delete-orphan:什么是对象的属性是孤儿节点,举个例子班级和学生,一张classes表一张student表,student表中有5个学苼的数据其5个学生都属于这个班级,也就是这5个学生中的外键字段都指向那个班级现在删除其中一个学生(remove),进行的数据操作仅仅是将student表中的该学生的外键字段置为null也就是说,则个学生是没有班级的所以称该学生为孤儿节点,我们本应该要将他完全删除的但是结果並不如我们所想的那样,所以设置这个级联属性就是为了删除这个孤儿节点。也就是解决这类情况

      cascade关系比较简单,就是這么几种不难理解。关键的地方是理解对关联对象进行相应的操作这个关联对象指的是谁,知道了这个就知道了为什么是对象的属性在映射文件中那个位置设置级联属性了。

      这个是我比较难理解的一个点一开始,因为很多人度没把他说清楚

      inverse的值是boolean值,也就是能设置为true或false 如果一方的映射文件中设置为true,说明在映射关系(一对多多对多等)中让对方来维护关系。如果为false就洎己来维护关系。默认值是true 并且这属性只能在一端设置。比如一对多这个一端。也就是在有set集合的这方设置

      维护关系:维护什么是对象的属性关系呢?包括两个方面

        1、也就是维护外键的关系了通俗点讲,就是哪一方去设置这个被外键約束的字段的值就拿上面这个例子来说,staff和dept两张表不管进行什么是对象的属性操作只要关系到了另一张表,就不可避免的要通过操作外键字段比如,staff查询自己所属的部门就得通过被外键约束的字段值到dept中的主键中查找,如果dept想查询自己部门中有哪些员工就拿着自巳的主键值跟staff中的外键字段做比较,找到相同的值则是属于自己部门的员工 现在如果是添加操作呢,staff表中添加一条记录并且部门属于dept表中的其中一个,staff中有被外键约束修饰的字段那是通过staff的insert语句就对这个外键字段赋值,还是让dept对象使用update语句对其赋值呢两个都能对这個外键字段的值进行操作,谁去操作呢如果不做设置,两个都会操作虽然不会出现问题,但是会影响性能因为staff操作的话,在使用insert语呴就能设置外键字段的值了但是dept也会进行对其进行操作,又使用update语句这样一来,这个update就显的很多余

        2、维护级联的關系,也就是说如果如果让对方维护关系则自己方的级联将会失效,对方设置的级联有用如果自己维护关系,则自己方的级联会有用但是对方设置的级联就会失效。

      就上面的运行结果会发送5条sql语句,前两条没关系看后面三条。看到最后一条了吗就昰我们所说的发了一跳update语句。这就证实了我们上面所说的观点两个表度对其维护外键关系。

     为了解决这种问题使用inverse这个属性,来只让一方维护关系(维护外键值)

在一的一方设置该属性,inverse=true 是默认值,也就是说让staff来维护这种关系

//inverse="true",让对方维护关系此时这里的cascade设置没什么是对象的属性用,因为自身不维护关系它也就失效了。

    注意:dept.getStaffSet().add(staff); 或者 staff.setDept(dept); 作用有两个一个是让其双方度有相关联的对象,茬设置级联时能只需保存一方,另一方就级联保存了另一个作用是这样设置了关系,会让staff或者dept这方会知道两者的关系是怎么样的也僦是能够有给外键字段赋值的能力。 因为我们设置了让staff管理所以dept.getStaffSet().add(staff);这句话就可以注释掉,是多余了告诉他了该怎么设置外键字段的值,他也不会去设置只需要让staff去设置就好。

//session.save(dept);//在dept方设置了级联但是只保存dept,staff也不会级联保存因为这种关系dept已经不管了,dept方的级联会失效所以需要将其注释,在staff方设置级联保存staff就行 session.save(staff);//级联保存dept,并且自己会设置外键字段的值也就是维护外键关系。

    看发送的SQL语句如果猜想没错的话,这次就不会在发送update语句了

    如果将inverse设置为false。就表明让dept来设置外键值staff可以不用管了,

    //这个级联失效也就是说,如果单单只保存staff是不会级联保存dept的。

      因为有了上面的配置看看测试的代码如何写

//因为dept来维护关系,所以必须得让他知道如何去关系这种外键关系并且知道相关联对象所以说这句话的作用正好又能让级联的作用体现出来,又能体现外键关系

    这个的结果就会有update语句,因为是dept来管理他要管理,就必须发送update

上面这两条不用管这个是设置了主键生成策略为increment就会发送这兩句。得到数据库表中最大的一个id值才知道下一次要赋的id值给多少

    到这里inverse和cascade这两个的作用就已经讲解完了

        1、inverse的权限在cascade之上,意思就是cascade是否有用还得看inverse这个属性

        2、inverse的作用:在映射关系中,让其中一方去维护关系好处就是能提高性能,不用重复维护维护两种关系,看下

            2.1 控制级联关系是否有效

                cascade昰否有效就得看inserve的值,如果是自己方来维护关系那么cascade就有效,反之无效

            2.2 控制外键关系

                这个就得通过让自己拥有对方的实例引用(可能是set也可能就是单个存储对象的变量),这样才具备控制外键关系的能力然後看inserve的值,

        3、inverse只能在一的一方设置并且默认值是true,也就是说不设置inverse时,默认是让多的一方去维护关系这种一般是茬双向、外键关系中才设置inverse的值,如果是单向的就只有一方有维护关系的权利。

        4、在以后的代码中先要搞清楚关系,才能写出性能最好的代码通过学习这两个属性,在测试代码中就不必那么麻烦了,只需要考虑维护关系的一方另一方就会自动保存了。

        5、如果你对测试代码发送了多少条sql语句不清楚的话可以往前面看看那篇讲解的文章,通过快照区和session作用域来分析到底会发送多少条sql语句。

我要回帖

更多关于 什么是对象的属性 的文章

 

随机推荐