1 单向多对一(多个A映射到一个B)
把A中的Integer B_id改成 B b,然后在A的映射文件中添加:
<many-to-one name="b" class="B的类全名" column="foreign key所在的字段名称" not-null="true"/>
注意:not-null属性比较傻X,意思为“设置关联的字段的值是否可以为空”且默认值是false,意思是可以为空,一般我们都需要改成true,让他不可以为空!
最后呢,因为A的成立需要依赖于B,所以在取值赋值的时候,要先初始化B,然后再把B赋给A的B b属性,否则A的Bb属性就会成null,很多错误都是这么出现的!!!
2 单向一对多(一个B映射到多个A)
在B中,用Set接口声明一个HashSet()类型的属性,用来盛放那么多的A,如:
private Set As = new HashSet();//注意,这里的As可以随便写,但为了方便,一般都写成多的一方的复数形式
public Set getAs() {
return As;
}
public void setAs(Set As) {
this.As = As;
}
既然B的pojo里多了一个属性,理所当然要在B的关联映射文件里也添加一个对应的关联元素:
<set name="As" table="A">
<key><column name="B_id"/></key> <!--这里写的是两个表之间的外键字段-->
<one-to-many class="A`s fullname"/> <!--对了,这里要写A的类全名-->
</set>
这时候,因为B的成立需要依赖于A了,所以在取值赋值的时候,要先初始化A,然后用:
B.getAs().add(A1);
B.getAs().add(A2);
B.getAs().add(A3);
...
先获得B中的HashSet()集合,然后把初始化好了的A一个个加入到这个集合里,才能完全初始化好B。
3 双向一对多关联(多个A一个B)
一言之,就是前面两项一起设置就行了。这时候数据加载起来就很灵活了,可以先加载"一"的一方,也可以先加载“多”的一方,具体就要看实际业务了。
3.1 cascade和inverse属性
在前面两种关联映射的应用中,如果“多”的一方个数非常多,在持久化的时候,session.save(b)后,还要save很多的a,最后hibernate才能自动关联起b和多个a,有没有方法让hibernate自动save多的一方,并且自动产生关联呢?
我们可以在“一”的hbm文件中的set元素中增加一个属性,如:
<set name="As" table="a" cascade="all">
<key>
<column name="b_id" not-null="true"/>
</key>
</set>
然后在加载数据的时候,只需让a和b互相关联,然后只持久化只有一个的b就可以了:
b.getAs().add(a);
a.setB(b);
session.save(b);
关于cascade属性的值:
1 | all | 对所有操作进行级联操作 |
2 | save-update | 执行保存和更新操作时进行级联操作 |
3 | delete | 执行删除时进行级联操作 |
4 | none | 不进行级联操作 |
注意:没有设置cascade属性时,hibernate不会进行级联操作!
问题:hibernate的级联操作跟MySql中的级联操作哪个性能更高更好用?
警告:设置了cascade属性之后,在持久化操作中,为了保证数据安全,hibernate会多执行一条update语句,而且是由”一“去一个个联系”多“,影响效率和性能!
如何破?请收看下期:神器的inverse属性。
来源:oschina
链接:https://my.oschina.net/u/1771562/blog/388623