通过设置来决定是有谁来维护表和表之间的关系的。
inverse常用于一对多双向关联关系中。
以student(学生)和class(班级)为例,它们之间的关系为一对多的关系,即一个学生只能属于一个班级,一个班级可以包含多个学
生。
学生类定义代码:
class student{
private int id;
private string name;
private class class;
//省略getter()和setter()方法
}
班级类定义代码:
class class{
private int id;
private string name;
private set students = new hashset();
//省略getter()和setter()方法
}
student类的映射文件:
<class name="student" table="student">
<id name="id" type="int" column="id">
<generator class="native" />
</id>
<property name="name" type="string" column="name" />
<many-to-one name="class" column="class_id" class="class" cascade="save-update" />
</class>
class类的映射文件:
<class name="class" table="class">
<id name="id" type="int" column="id">
<generator class="native" />
</id>
<property name="name" type="string" column="name" />
<set name="students" table="student" cascade="save-update" inverse="false">
<key column="class_id" />
<one-to-many class="student" />
</set>
</class>
希望你能对这两个映射文件所表达的数据库模式有正确的认识。即student表中存在一个名为class_id的字段,它和class表中的id字段是主外键关系。那个inverse属性就是用来规定是由谁(student或class)来维护这个主外键关系的。
inverse的默认值为false。
在处理逻辑代码中,如下:
class c1 = new class();
c1.setname("一班");
student s1 = new student();
student s2 = new student();
s1.setname("jason");
s2.setname("tom");
c1.getstudents().add(s1);
c2.getstudents().add(s2);
s1.setclass(c1);
s2.setclass(c1); //注释1
session.save(c1);
上面的代码会使hibernate执行五条sql语句,其中前三条是insert插入语句,后两条是update更新语句。插入就不用说了,那么为什么还要有更新语句呢?这是因为class类映射文件的<set>元素中指定了inverse="false",这就告之hibernate:student表与class表的主外键关系是由class类来维护的。当执行save后,执行了三条insert语句,这三条语句中的后两条是插入到student表的,它们的class_id字段是通过s1.getclass().getid()取出的,假如我将上面“注释1”处修改为s2.setclass(c2);(c2是另一个class对象,可能是持久化对象),这样,主外键关系不就乱了吗。为了保证主外键关系,hibernate在这种情况下会再执行两条update语句来更改student表中两个新插入记录的class_id字段,当然,这时class_id字段的取值是从c1对象中直接取得,而不再是s1.getclass().getid()方式了。
如果我们将class类映射文件的<set>元素中的inverse属性修改为true,这就是告诉hibernate:class类不维护主外键关系了,这个任务就交给了student类。于是,我们再执行上面的代码,hibernate就会只执行三条insert语句,而不会执行任何update语句。因为hibernate会通过student类的s1.getclass().getid()和s2.getclass().getid()来确定class_id字段的值。
故,为了节省数据库资源,省却不必要的update语句,我们一般建议在一对多双向关联关系中,将一方的inverse属性设置为true,即将主外键的关系交由多方来维护。
打个比方:在一个公司中,是老板认识所有的员工容易,还是所有员工认识老板容易?
我是一个hibernate的初学者,前两天刚刚研究了一下inverse属性,有所心得。写了这么多东西,希望能对你有所帮助。