映射实体关联关系

约定不等于承诺〃 2022-07-13 18:51 324阅读 0赞

映射一对一关联

有两种方法,一种按照外键映射,一种按照主键映射。

1.按照外键映射

  1. 一个类中有两个一对一关联。
  2. class A{
  3. id;
  4. name;
  5. B home;
  6. B company;
  7. }
  8. class B{
  9. string address;
  10. string street;A a;
  11. }
  12. A
  13. id
  14. name
  15. home_id//指向B表中的id,外键
  16. company_id//指向B表中的id,外键
  17. B
  18. address
  19. street
  20. id

A映射文件:

  1. <many-to-one
  2. name="home"
  3. class="B"
  4. column="home_id"
  5. />
  6. <many-to-one
  7. name="company"
  8. class="B"
  9. column="company_id"
  10. unique="true"//保证唯一
  11. cascsde="all"
  12. />

B映射文件:

  1. <one-to-one //只能使用一次,所以要映射两次的话,把B定义为抽象类,用两个类继承,让后再每个类中用one-to-one
  2. name="a"
  3. class="A"
  4. property-ref="home"
  5. />

2.按照主键映射

  1. 只有一个一对一关联。
  2. class A{
  3. id;name
  4. B b;
  5. }
  6. class B{
  7. id
  8. address;A a
  9. }
  10. A
  11. id
  12. name
  13. //这两个表共享主键,id是一样的
  14. B
  15. id//作为主键的同时,作为外键参照A表
  16. address

A映射文件:

  1. <one-to-one name="b"
  2. class="B"
  3. cascade="true"
  4. />

B映射文件:

  1. <id>
  2. <generator class="foreign">//OID要用foreign策略
  3. <param name="property">a</param>
  4. </generator>
  5. </id>
  6. <one-to-one name="a"
  7. class="A"
  8. constrained="true"//表示主键id同时作为外键参照A
  9. />

映射单向多对多关联

  1. class A{//这两个类是多对多关系
  2. id
  3. nameSet BS = new HashSet();
  4. }
  5. class B{
  6. id
  7. address
  8. }

要建立一个中间表

  1. A
  2. id
  3. name
  4. B
  5. id
  6. address
  7. A_B
  8. A_id//A_id和B_id作为联合主键,A_id作为A表的外键,B_id作为B表的外键
  9. B_id

A映射文件:

  1. <set
  2. name="BS"
  3. table="A_B"
  4. cascade="save-update"
  5. lazy="true"
  6. >
  7. <key column="A_id">
  8. <many-to-many column="B_id" class="B"/>
  9. </set>

也可以用list:

  1. <list
  2. name="BS"
  3. table="A_B"
  4. cascade="save-update"
  5. lazy="true"
  6. >
  7. <key column="A_id"><list-index column="索引字段">
  8. <many-to-many column="B_id" class="B"/>
  9. </list>

映射双向多对多关联关系

  1. 双向多对多必须把一端的inversetrueinversetrue一段可以使用<set>,<bag>。inversefalse的一端,可以使用<set>,<list>,<map>,<idbag>。

1.关联两端使用元素

  1. class A{
  2. id
  3. name
  4. set BS
  5. }
  6. class B{
  7. id
  8. adress
  9. set AS
  10. }//表和单向多对多一样

A映射文件:

  1. <set
  2. name="BS"
  3. table="A_B"
  4. cascade="save-update"
  5. lazy="true"
  6. >
  7. <key column="A_id">
  8. <many-to-many column="B_id" class="B"/>
  9. </set>

B映射文件

  1. <set
  2. name="AS"
  3. table="A_B"
  4. inverse="true"
  5. cascade="save-update"
  6. lazy="true"
  7. >
  8. <key column="B_id">
  9. <many-to-many column="A_id" class="A"/>
  10. </set>

2.inverse为true的一端使用bag

  1. 为什么Inversetrue的那端不能使用list,map之类的呢:因为这些元素有排序。
  2. 如果两个类都是list集合,而没有inverse的那端可以更新索引,有inverse的那端不能同步更新索引,所以如果索引变化了就不会同步更新,就出问题。
  3. 如果在inverse那端勒种定义的是list,那么就是用bag元素,<bag>和<idbag>的区别是:都允许放重复对象,都不支持索引位置排序,<idbag>要求连接表中一定要有代理主键,<bag>没有这个要求,<bag>一般用于一对多或多对多的inverse端。
  4. <bag
  5. name="AS"
  6. table="A_B"
  7. cascade="save-update"
  8. lazy="true"
  9. >
  10. <key column="B_id">
  11. <many-to-many column="A_id" class="A"/>
  12. </bag>

3.使用组件类集合

  1. 两个多对多的类可以使用一个组件类型的类,来实现多对多,而不是用主键当外键关联两个类的表。
  2. calss A{
  3. id
  4. name
  5. set ab//A_B类型
  6. }
  7. class B{
  8. id
  9. adress
  10. Set ba//A_B类型
  11. }
  12. class A_B{//使用组件关联两个多对多的类
  13. A a
  14. B b
  15. name
  16. }
  17. A
  18. id
  19. name
  20. B
  21. id
  22. address
  23. A_B//表中所有字段作为联合主键
  24. A_id//外键
  25. B_id//外键
  26. name

A映射文件:

  1. <set
  2. name="ab"
  3. table="A_B"
  4. cascade=""
  5. lazy=""
  6. >
  7. <key column="A_id">
  8. <composite-element class="A_B">
  9. <parent name="a">
  10. <many-to-one name="b" class="B" column='B_id">
  11. <property>
  12. </composite>
  13. </set>

B的映射文件:

  1. <set
  2. name="ba"
  3. table="A_B"
  4. cascade=""
  5. lazy="" inverse="true"
  6. >
  7. <key column="B_id">
  8. <composite-element class="A_B">
  9. <parent name="b">
  10. <many-to-one name="a" class="A" column='A_id">
  11. <property>
  12. </composite>
  13. </set>

4.把多对多关联分解为两个一对多关联

  1. 在组件类型中添加OID,可以打一个多对多拆成两个一对多。

A映射文件:

  1. <set
  2. name="ab"
  3. cascade=""
  4. lazy="" inverse="true"//一对多,一这边最好要加inverse="true"
  5. >
  6. <key column="A_id">
  7. <one-to-many class="A_B">
  8. </set>

B映射文件:

  1. <set
  2. name="ba"
  3. cascade=""
  4. lazy="" inverse="true"//一对多,一这边最好要加inverse="true"
  5. >
  6. <key column="B_id">
  7. <one-to-many class="A_B">
  8. </set>

因为A_B现在有OID了,所以有映射文件:

  1. <class name="" table>
  2. <id>
  3. <property>
  4. <many-to-one name="a" column="A_id" class="A"/>
  5. <many-to-one name="b" column="B_id" class="B"/>
  6. </class>

发表评论

表情:
评论列表 (有 0 条评论,324人围观)

还没有评论,来说两句吧...

相关阅读