@Beeder
2017-12-22T03:50:54.000000Z
字数 5433
阅读 739
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("熊二");// 双向关联 beginc1.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方法//定义另一多方的集合rolesprivate 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方法//定义另一多方的集合usersprivate 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>