@Beeder
2017-12-22T11:50:54.000000Z
字数 5433
阅读 653
javaWeb
关系 | 表名 | 备注 |
---|---|---|
一方 | Customer | 客户 |
多方 | Linkman | 联系人 |
public class Customer {
//引入HashSet集合,并提供get、set方法
//Hibernate框架默认的集合是set集合,集合必须要自己手动的初始化
private Set<Linkman> linkmans = new HashSet<Linkman>();
private Long cust_id;
private String cust_name;
private Long cust_user_id;
private Long cust_create_id;
private String cust_source;
/*
省略……
*/
}
<class name="com.itheima.domain.Customer" table="cst_customer">
<id name="cust_id" column="cust_id">
<generator class="native"/>
</id>
<property name="cust_name" column="cust_name"/>
<property name="cust_user_id" column="cust_user_id"/>
<property name="cust_create_id" column="cust_create_id"/>
<property name="cust_source" column="cust_source"/>
<!-- 省略……
-->
<!--一方配置-->
<set name="linkmans">
<!--设置外键lkm_cust_id-->
<key column="lkm_cust_id"/>
<one-to-many class="com.itheima.domain.Linkman"/>
</set>
</class>
public class Linkman {
//创建一方对象(不赋值),提供get、set方法
private Customer customer;
private Long lkm_id;
private String lkm_name;
private String lkm_phone;
/*
省略……
/*
}
<class name="com.itheima.domain.Linkman" table="cst_linkman">
<id name="lkm_id" column="lkm_id">
<generator class="native"/>
</id>
<property name="lkm_name" column="lkm_name"/>
<property name="lkm_gender" column="lkm_gender"/>
<property name="lkm_phone" column="lkm_phone"/>
<!-- 省略……
-->
<!--多方配置-->
<many-to-one name="customer" class="com.itheima.domain.Customer" column="lkm_cust_id"/>
</class>
配置好持久化类后,默认必须使用双向关联才能操作数据,否则会报错
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
// 保存客户和联系人的数据
Customer c1 = new Customer();
c1.setCust_name("美美");
// 创建2个联系人
Linkman l1 = new Linkman();
l1.setLkm_name("熊大");
Linkman l2 = new Linkman();
l2.setLkm_name("熊二");
// 双向关联 begin
c1.getLinkmans().add(l1);
c1.getLinkmans().add(l2);
l1.setCustomer(c1);
l2.setCustomer(c1);
// 双向关联 end
// 保存数据
session.save(c1);
session.save(l1);
session.save(l2);
tr.commit();
关键字:cascade
/*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="save-update,delete" />
<!--例:-->
<many-to-one name="customer" class="com.itheima.domain.Customer" column="lkm_cust_id" cascade="save-update,delete"/>
在解除了父子关系的时候.会将子方记录就直接删除。
<one-to-many class="com.itheima.domain.Linkman" cascade="delete-orphan"/>
/**
* 解除关系:从集合中删除联系人
* 解除关系的同时也会将子方记录删除
*/
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction();
// 先获取到客户
Customer c1 = session.get(Customer.class, 1L);
Linkman l1 = session.get(Linkman.class, 1L);
// 解除
c1.getLinkmans().remove(l1);
tr.commit();
<!--设置cascade="save-update"-->
<one-to-many class="com.itheima.domain.Linkman" cascade="save-update"/>
// 保存客户和联系人的数据
/*
* 一方和多方数据都会保存到数据库
*/
Customer c1 = new Customer();
c1.setCust_name("美美");
// 创建2个联系人
Linkman l1 = new Linkman();
l1.setLkm_name("熊大");
Linkman l2 = new Linkman();
l2.setLkm_name("熊二");
// 单向关联:一方关联多方
c1.getLinkmans().add(l1);
c1.getLinkmans().add(l2);
// 保存数据
session.save(c1);
<!--设置cascade="save-update"-->
<many-to-one name="customer" class="com.itheima.domain.Customer" column="lkm_cust_id" cascade="save-update,delete"/>
// 保存客户和联系人的数据
/*
* 一方和多方数据都会保存到数据库
*/
Customer c1 = new Customer();
c1.setCust_name("美美");
// 创建2个联系人
Linkman l1 = new Linkman();
l1.setLkm_name("熊大");
Linkman l2 = new Linkman();
l2.setLkm_name("熊二");
//单向关联:多方关联一方
l1.setCustomer(c1);
l2.setCustomer(c1);
// 保存
session.save(l1);
关键字:inverse
重点:只有一方能使用
防止产生多余的SQL语句
实现步骤:想修改客户和联系人的关系,进行双向关联,双方都会维护外键,会产生多余的SQL语句。
分析原因:session的一级缓存中的快照机制,会让双方都更新数据库,产生了多余的SQL语句。
解决方法:'一方'放弃维护外键(在'一方'的映射配置文件<set>标签上配置一个inverse=”true”.true:放弃维护.false:不放弃.默认值是false)。
<!--放弃维护外键-->
<!--'一方'放弃维护外键后,将无法对外键进行操作-->
<set name="linkmans" inverse="true">
<key column="lkm_cust_id"/>
<one-to-many class="com.itheima.domain.Linkman"/>
</set>
重点:必须有一方放弃外键维护
关系 | 表名 | 备注 |
---|---|---|
多方 | User | 用户 |
多方 | Role | 角色 |
public class User {
//引入HashSet集合,并提供get、set方法
//定义另一多方的集合roles
private Set<Role> roles = new HashSet<Role>();
private Long user_id;
private String user_code;
private String user_name;
private String user_password;
private String user_state;
/*
省略……
*/
}
User.hbm.xml
<class name="com.itheima.domain.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"/>
<!--配置多对多
name:JavaBean中的集合名称
table:中间表名称(用于维护外键)
-->
<!--Hibernate会自动生成中间表sys_user_role-->
<set name="roles" table="sys_user_role">
<!-- 当前对象在中间表的外键的名称 -->
<key column="user_id"/>
<!--
class 集合中存入对象,对象的全路径
column 集合中对象在中间表的外键的名称
-->
<many-to-many class="com.itheima.domain.Role" column="role_id"/>
</set>
</class>
Role.hbm.xml
public class Role {
//引入HashSet集合,并提供get、set方法
//定义另一多方的集合users
private Set<User> users = new HashSet<User>();
private Long role_id;
private String role_name;
private String role_memo;
/*
省略……
*/
}
<class name="com.itheima.domain.Role" table="sys_role">
<id name="rid" column="rid">
<generator class="native"/>
</id>
<property name="rname" column="rname"/>
<!-- 多对多必须要有一方放弃外键的维护的 -->
<set name="users" table="sys_user_role" inverse="true">
<key column="rid"/>
<many-to-many class="com.itheima.domain.User" column="uid"/>
</set>
</class>