Hibernate高级实体关联映射之多值的实体关联(多对多关联的两种思路之一)
hibernate反对多对多关联的使用,因为联结表中的额外列通常是不可能避免的。如果联结表有一些额外的列,而不只是两个外键列时,该怎么办?
我们可以用一对多模拟多对多的关系。可以用两种常用的策略把这样一种结构映射到java类。第一种策略需要一个用于联结表的中间实体类,并通过一对多的关联而被映射。第二种策略通过给联结表使用一个值类型的类来利用组件的集合。
我们实现第一种策略:把联结表映射到中间实体
pom.xml:
resources/hibernate.cfg.xml:
pojo/Teacher.java:
pojo/Teacher.hbm.xml:
pojo/Student.java:
pojo/Student.hbm.xml:
pojo/MyClass.java:
pojo/MyClass.hbm.xml:
util/HibernateUtil.java:
util/Manager.java:
表结构:
上例中,联结表的主键是TEACHER_ID,STUDENT_ID的复合。因而,对应的实体类也有一个复合键,为了方便起见,把它封装在一个静态的嵌套类中了,记得该静态嵌套类要实现equals()和hashCode()方法。注意:复合键值由应用程序分配,你可以看看MyClass.java的构造方法,它如何设置字段值,并通过在关联的任意一端管理集合来确保参照完整性。
联结表对应的实体类被映射为不可变---你创建之后永远不用更新任何属性。hibernate直接访问<composite-id>字段---在这个被嵌套的类中不需要获取方法和设置方法。两个<many-to-one>映射实际上是只读的;insert和update被设置为false.这是必需的,因为列被映射两次:一次在复合键中(负责值的插入),另一次用于多对一的关联。
这个策略的主要好处在于双向导航的可能性;缺点是要用更复杂的代码管理MyClass实体实例,创建和移除关联---它们必须被独立地被保存和删除。
这个例子是用bag实现的,如果使用set也是可以的。但不确定list,map行不行,没有测试!!!!