双向关联
Inverse是双向关联的基本概念。对于多数是实体,一般不用双向关联,而是采用一对多的关联,many-to-one不存在inverse属性。其他默认值inverse=”false”
多方配置
<class name="org.pojo.many2one.Student"table="tb_student">
<id name="stuId">
<generator class="sequence">
<param name="sequence">seq_id</param>
</generator>
</id>
<property name="stuName"></property>
<many-to-one name="team" class="org.pojo.many2one.Team"fetch="join">
<column name="team"></column>
</many-to-one>
</class>
一方配置
<class name="org.pojo.many2one.Team"table="tb_team">
<id name="teamId">
<generator class="sequence">
<param name="sequence">seq_id</param>
</generator>
</id>
<property name="teamName"></property>
<set name="students" inverse="true"lazy="false" fetch="join">
<key>
<column name="team"></column>
</key>
<one-to-many class="org.pojo.many2one.Student"/>
</set>
</class>
备注:我们说inverse设立不当会导致性能低下,其实是说inverse设立不当,会产生多余重复的SQL语句甚至致使JDBC exception 的 throw。这是我们在建立实体类关系时必须需要关注的地方。一般来说,inverse=true 是推荐使用,双向关联中双方都设置 inverse=false 的话,必会导致双方都重复更新同一个关系。但是如果双方都设立inverse=true
的话,双方都不维护关系的更新,这也是不行的,好在一对多中的一端:many-to-one 默认是 inverse=false,避免了这种错误的产生。但是对多对就没有这个默认设置了,所以很多人经常在多对多的两端都使用 inverse=true,结果导致连接表的数据根本没有记录,就是因为他们双分都没有责任维护关系。所以说,双向关联中最好的设置是一端为 inverse=true,一端为 inverse=false。一般 inverse=false 会放在多的一端,那么有人提问了,many-to-many两边都是多的,inverse 到底放在哪儿?其实 hibernate 建立多对多关系也是将他们分离成两个一对多关系,中间连接一个连接表。所以通用存在一对多的关系,也可以这样说:一对多是多对多的基本组成部分inverse 的值有两种,“true”和“false”。inverse="false"是默认的值,如果设置为 true 则表示对象的状态变化不会同步到数据库 ;设置成false 则相反; inverse 的作用:在 hibernate 中是通过 inverse 的设置来决定是有谁来维护表和表之间的关系的。 set 的 inverse 属性决定是否把对 set 的改动反映到数据库中去。inverse=false————反映; inverse=true————不反映”inverse 属性默认为 false
多对多关联
多对多关联都为双向关联,多对多实际上是两个一对多的关联。
案例:学生和老师之间的的多对多关系,使用中间表Student_Teacher来中转。使用studentID和teacherID为联合主键。
public class Teacher {
private int teacherId;
private String teacherName;
private Set student_teacher = new HashSet();
get set……
public class Student {
private int studentId;
private String studentName;
private Set student_teacher = new HashSet();
get set……
映射文件
Student.hbm.xml
<class name="org.pojo.many2many.Student"table="tb_student">
<id name="studentId">
<generator class="sequence">
<param name="sequence">seq_id</param>
</generator>
</id>
<property name="studentName"></property>
<set name="student_teacher" table="tb_student_teacher" cascade="save-update">
<key>
<column name="studentId"></column>
</key>
<many-to-many class="org.pojo.many2many.Teacher" column="teacherId"></many-to-many>
</set>
</class>
Teacher.hbm.xml
<class name="org.pojo.many2many.Teacher"table="tb_teacher">
<id name="teacherId">
<generator class="sequence">
<param name="sequence">seq_id</param>
</generator>
</id>
<property name="teacherName"></property>
<set name="student_teacher" table="tb_student_teacher" inverse="true">
<key>
<column name="teacherId"></column>
</key>
<many-to-many class="org.pojo.many2many.Student" column="studentId"></many-to-many>
</set>
</class>
测试
tx.begin();
Student s1 = new ();
s1.setStudentName("张三");
Student s2 = new Student();
s2.setStudentName("李四");
Teacher t1 = new Teacher();
t1.setTeacherName("张三丰");
Teacher t2 = new Teacher();
t2.setTeacherName("张翠三");
Set<Student> students = new HashSet< Student>();
students.add(s1);
students.add(s2);
Set<Teacher> teachers = new HashSet<Teacher>();
teachers.add(t1);
teachers.add(t2);
s1.setStudent_teacher(teachers);
s2.setStudent_teacher(teachers);
session.save(t1);
session.save(t2);
session.save(s1);
session.save(s2);
tx.commit();