Hibernate关联关系映射
一对多:
一对多Demo
* 客户的JavaBean如下
public class Customer {
private Long cust_id;
private Set<Linkman> linkmans = new HashSet<Linkman>();
}
* 联系人的JavaBean如下
public class Linkman {
private Long lkm_id;
private Customer customer;
}
编写客户和联系人的映射配置文件(注意一对多的配置编写)
* 客户的映射配置文件如下
<class name="com.xx.xx.Customer" table="cst_customer">
<id name="cust_id" column="cust_id">
<generator class="native"/>
</id>
<!-- 配置关联对象 set标签: name属性:多的一方的集合的属性名称-->
<set name="linkmans">
<!-- key标签 : column属性:多的一方的外键的名称 -->
<key column="lkm_cust_id"/>
<!-- one-to-many标签: class属性:多的一方的类全路径 -->
<one-to-many class="com.itheima.domain.Linkman"/>
</set>
</class>
* 联系人的映射配置文件如下
<class name="com.xx.xx.Linkman" table="cst_linkman">
<id name="lkm_id" column="lkm_id">
<generator class="native"/>
</id>
<!-- 配置关联对象: many-to-one:标签.代表多对一.
* name :一的一方的对象的名称.
* class :一的一方的类的全路径.
* column :表中的外键的名称.
-->
<many-to-one name="customer" class="com.itheima.domain.Customer" column="lkm_cust_id"/>
</class>
级联保存:
* 保存客户Customer,同时级联保存联系人Linkman. 在set集合上配置cascade=”save-update”
* 保存联系人Linkman,级联保存客户Customer 在many-to-one上配置cascade="save-update"
级联删除:
* 删除客户Customer的时候,删除联系人Linkman,在set集合上配置 cascade=”delete”
* 删除联系人Linkman,同时删除客户Customer,在many-to-one上配置cascade="delete"
双方都维护外键的时候,会产生多余的SQL语句。
* 想修改客户和联系人的关系,进行双向关联,双方都会维护外键,会产生多余的SQL语句。
* 产生的原因:session的一级缓存中的快照机制,会让双方都更新数据库,产生了多余的SQL语句。
如果不想产生多余的SQL语句,那么需要一方来放弃外键的维护!
* 在<set>标签上配置一个inverse=”true”.true:放弃.false:不放弃.默认值是false
一方放弃外键的维护,多方配置级联操作。
cascade用来级联操作(保存、修改和删除)
inverse用来维护外键的
级联的取值(cascade的取值)
* none -- 不使用级联
* save-update -- 级联保存或更新
* delete -- 级联删除
* delete-orphan -- 孤儿删除.(注意:只能应用在一对多关系)
* all -- 除了delete-orphan的所有情况.(包含save-update,delete)
* all-delete-orphan -- 包含了delete-orphan的所有情况.(包含save-update,delete,delete-orphan)
孤儿删除(孤子删除),只有在一对多的环境下才有孤儿删除
* 在一对多的关系中,可以将一的一方认为是父方.将多的一方认为是子方.孤儿删除:在解除了父子关系的时候.将子方记录就直接删除。<many-to-one cascade="delete-orphan" />
多对多
public class User { //用户
private Long user_id;
private String user_code;
private String user_name;
private String user_password;
private String user_state;
private Set<Role> roles = new HashSet<Role>();
}
public class Role { //角色
private Long role_id;
private String role_name;
private String role_memo;
private Set<User> users = new HashSet<User>();
}
<class name="com.xx.xx.User" table="sys_user">
<id name="user_id" column="user_id">
<generator class="native"/>
</id>
<property name="user_code" column="user_code"/>
<property name="user_name" column="user_name"/>
<property name="user_password" column="user_password"/>
<property name="user_state" column="user_state"/>
<set name="roles" table="sys_user_role">
<key column="user_id"/>
<many-to-many class="com.xx.xx.Role" column="role_id"/>
</set>
</class>
<class name="com.xx.xx.Role" table="sys_role">
<id name="role_id" column="role_id">
<generator class="native"/>
</id>
<property name="role_name" column="role_name"/>
<property name="role_memo" column="role_memo"/>
<set name="users" table="sys_user_role">
<key column="role_id"/>
<many-to-many class="com.xx.xx.User" column="user_id"/>
</set>
</class>
多对多进行双向关联的时候:必须有一方去放弃外键维护权
如果建立了双向的关系 一定要有一方放弃外键维护权.
用户级联角色.在User.hbm.xml中<set>上配置 cascade="save-update"
角色级联用户 在Role.hbm.xml中配置cascade="save-update"
级联删除:删除角色 级联删除 用户.