hibernate之inverse=true相关配置讲解
首先inverse=”true”是在双向关联里面使用单向关联没有这个配置
inverse – 标记由哪一方来维护关联关系(双向关联中会用到)
inverse默认值为false
如果inverse设置为true,表示将由对方维护两者之间的关联关系
举例说明
OR映射文件
contactPerson映射文件
<class name="cn.com.leadfar.hibernate.ContactPerson" table="t_person" >
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
<property name="address"/>
<property name="qq" />
<!-- 多对一这端gid要和一一端保持一致 如果不保持一致 指向group的一种引用-->
<many-to-one name="group" column="gid1"></many-to-one>
</class>
Group的相关配置文件
<class name="cn.com.leadfar.hibernate.Group" table="t_group" >
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 没有设置inverse=true表示任意一端管理都可以 -->
<!-- 设置inverse=true标识强制一的一端管理他们的关联关系 默认是inverse=false的情况双方都可以管理关联关系 -->
<set name="persons" lazy="extra" >
<!-- 要跟多的一端gid保持一致 -->
<key column="gid2"></key>
<one-to-many class="cn.com.leadfar.hibernate.ContactPerson"/>
</set>
</class>
<set name="students“ lazy=“false” inverse=“true”>
<key column="classesid" ></key>
<one-to-many class=“cn.com.leadfar.Student" />
</set>
强制规定在对方去联双方的联关系
Inverse=”false”表示双方都可以管理这个关联关系(缺省情况下)
配置文件
当Inverse=”false”示例
代码:
session.beginTransaction();
ContactPerson cp1 = new ContactPerson("炉小鱼");
session.save(cp1);
ContactPerson cp2 = new ContactPerson("比尔盖茨");
session.save(cp2);
ContactPerson cp3 = new ContactPerson("巴菲特");
session.save(cp3);
Group g1 =new Group("组0");
session.save(g1);
Group g2 = new Group("组1");
session.save(g2);
Group g3 = new Group("组3");
session.save(g3);
Set<ContactPerson> persons1 = new HashSet<ContactPerson>();
persons1.add(cp1);
persons1.add(cp2);
g1.setPersons(persons1);
Set<ContactPerson> persons2 = new HashSet<ContactPerson>();
persons2.add(cp3);
g3.setPersons(persons2);
session.getTransaction().commit();
输出
由一的一端进行维护所有gid1就是null
//**************从多的一端和一的一端进行双向管理他们的关联关系****************************
session.beginTransaction();
ContactPerson cp1 = new ContactPerson("炉小鱼");
session.save(cp1);
ContactPerson cp2 = new ContactPerson("比尔盖茨");
session.save(cp2);
ContactPerson cp3 = new ContactPerson("巴菲特");
session.save(cp3);
Group g1 =new Group("组0");
g1.addPerson(cp1);
g1.addPerson(cp2);
session.save(g1);//g1变成了持久化对象状态,现在拥有了数据库标识
//还要建立
cp1.setGroup(g1);
cp2.setGroup(g1);
Group g2 = new Group("组1");
session.save(g2);////g2变成了持久化对象状态,现在拥有了数据库标识
Group g3 = new Group("组3");
g3.addPerson(cp3);
session.save(g3);////g3变成了持久化对象状态,现在拥有了数据库标识
cp3.setGroup(g3);
session.getTransaction().commit();
输出
从一的一端去管理他们的关联关系
//*****************从一的一端去关联他们的关联关系***************************
Group g1 = new Group("组0");
session.save(g1);
Group g2 = new Group("组1");
session.save(g2);
Group g3 = new Group("组3");
session.save(g3);
ContactPerson cp1 = new ContactPerson("炉小雨");
cp1.setGroup(g1);//建立关联关系
session.save(cp1);
ContactPerson cp2 = new ContactPerson("比尔盖茨");
cp2.setGroup(g1);//建立关联关系
session.save(cp2);
ContactPerson cp3 = new ContactPerson("巴菲特");
cp3.setGroup(g3);//建立关联关系
session.save(cp3);
输出
以上就是inverse=”false”的情况下在多的一端和一的一端都可以管理他们的关联关系
跟着给一的一端设置inverse=true
<class name="cn.com.leadfar.hibernate.Group" table="t_group" >
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 没有设置inverse=true表示任意一端管理都可以 -->
<set name="persons" lazy="extra" inverse="true" >
<!-- 要跟多的一端gid保持一致 -->
<key column="gid2"></key>
<one-to-many class="cn.com.leadfar.hibernate.ContactPerson"/>
</set>
</class>
继续运行从多的一端运行的管理测试代码
我们分析这段代码
g1.addPerson(cp1); //如果在一的一端设置了inverse=true,那么这段代码就没有用了
g1.addPerson(cp2); //如果在一的一端设置了inverse=true,那么这段代码就没有用了,所以gid字段就为null了
cp1.setGroup(g1);//多的一端管理会起作用
cp2.setGroup(g1);//多的一端管理会起作用
只有这种方式的关联才会是gid1有值
这就是inverse=-true带给我们一个直观的结果,设置inverse=true他将不再由一的一端去管理一和多之间的关联关系
Inverse=true 作用
刚才字段设置成两个是为了看的更清楚 设置了inverse=true表示哪个字段有值哪个字段没有值会看的更清楚 如果你设置了inverset=true表示强制在哪一端管理他们的关联关系 一般要设置字段保持一致
<class name="cn.com.leadfar.hibernate.ContactPerson" table="t_person" >
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
<property name="address"/>
<property name="qq" />
<!-- 多对一这端gid要和一一端保持一致 如果不保持一致 指向group的一种引用-->
<many-to-one name="group" column="gid"></many-to-one>
</class>
<class name="cn.com.leadfar.hibernate.Group" table="t_group" >
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 没有设置inverse=true表示任意一端管理都可以 -->
<!-- 设置inverse=true标识强制一的一端管理他们的关联关系 -->
<set name="persons" lazy="extra" inverse="true" >
<!-- 要跟多的一端gid保持一致 -->
<key column="gid"></key>
<one-to-many class="cn.com.leadfar.hibernate.ContactPerson"/>
</set>
</class>
//没有设置inverse="true"那么在更新一的一端的数据时
Group g = (Group) session.load(Group.class, 1);
System.out.println(g.getName());
g.setName("好朋友");
session.getTransaction().commit();
在多层应用架构里面 如果要更新一个对象 首先是要根据id查询出来,将id对象显示在更新界面里面 最后在提交到更新的action里面,说这个的意思是通常更新不是这样去更新的 提交到后台的更新action里面要new 模型 里面赋予相关的id值以及相关的属性用这种方式来更新更加常见
ContactPerson cp1 = new ContactPerson();
cp1.setId(1);
cp1.setName("helloworld");
cp1.setAddress("平川");
cp1.setQq("3333222");
//这时更新gid会为null
session.update(cp1);
session.getTransaction().commit();
输出:
session.beginTransaction();
ContactPerson cp1 = new ContactPerson();
cp1.setId(1);
cp1.setName("helloworld");
cp1.setAddress("平川");
cp1.setQq("3333222");
//这时更新gid会为null
//我们得记住他的关联
Group g1 = new Group();
g1.setId(1);
cp1.setGroup(g1);
session.update(cp1);
输出
session.beginTransaction();
Group g1 = new Group();
g1.setId(1);
g1.setName("朋友");
session.update(g1);
我很不希望这种情况发生,我们发现关联丢失了如果这个关联想要不丢失怎么办呢?
最简单的方式就是设置inverse=true
设置inverse=true的结果后
session.beginTransaction();
Group g1 = new Group();
g1.setId(1);
g1.setName("sb34朋友");
ContactPerson cp1 = new ContactPerson();
cp1.setId(1);
ContactPerson cp2 = new ContactPerson();
cp2.setId(2);
g1.addPerson(cp1);
g1.addPerson(cp2);
session.update(g1);
session.getTransaction().commit();
发现集合里面保存的东西我们是不管他的,所以inverse=true不管在这个集合里面有没有数据
public class Group {
private int id;
private String name;
private Set<ContactPerson> persons = new HashSet<ContactPerson>();
在保存和更新的时候都不会去同步集合里面的数据就当集合里面的数据不存在不管又还是没有我都不管