[关闭]
@Beeder 2017-12-22T11:50:54.000000Z 字数 5433 阅读 653

Hibernate框架操作 关联关系映射

javaWeb

上一篇:Hibernate框架

一对多映射

关系 表名 备注
一方 Customer 客户
多方 Linkman 联系人

基本操作

一方配置

一方的JavaBean
  1. public class Customer {
  2. //引入HashSet集合,并提供get、set方法
  3. //Hibernate框架默认的集合是set集合,集合必须要自己手动的初始化
  4. private Set<Linkman> linkmans = new HashSet<Linkman>();
  5. private Long cust_id;
  6. private String cust_name;
  7. private Long cust_user_id;
  8. private Long cust_create_id;
  9. private String cust_source;
  10. /*
  11. 省略……
  12. */
  13. }
一方的映射配置文件
  1. <class name="com.itheima.domain.Customer" table="cst_customer">
  2. <id name="cust_id" column="cust_id">
  3. <generator class="native"/>
  4. </id>
  5. <property name="cust_name" column="cust_name"/>
  6. <property name="cust_user_id" column="cust_user_id"/>
  7. <property name="cust_create_id" column="cust_create_id"/>
  8. <property name="cust_source" column="cust_source"/>
  9. <!-- 省略……
  10. -->
  11. <!--一方配置-->
  12. <set name="linkmans">
  13. <!--设置外键lkm_cust_id-->
  14. <key column="lkm_cust_id"/>
  15. <one-to-many class="com.itheima.domain.Linkman"/>
  16. </set>
  17. </class>

多方配置

多方的JavaBean
  1. public class Linkman {
  2. //创建一方对象(不赋值),提供get、set方法
  3. private Customer customer;
  4. private Long lkm_id;
  5. private String lkm_name;
  6. private String lkm_phone;
  7. /*
  8. 省略……
  9. /*
  10. }
多方的映射配置文件
  1. <class name="com.itheima.domain.Linkman" table="cst_linkman">
  2. <id name="lkm_id" column="lkm_id">
  3. <generator class="native"/>
  4. </id>
  5. <property name="lkm_name" column="lkm_name"/>
  6. <property name="lkm_gender" column="lkm_gender"/>
  7. <property name="lkm_phone" column="lkm_phone"/>
  8. <!-- 省略……
  9. -->
  10. <!--多方配置-->
  11. <many-to-one name="customer" class="com.itheima.domain.Customer" column="lkm_cust_id"/>
  12. </class>

双向关联方式保存数据

配置好持久化类后,默认必须使用双向关联才能操作数据,否则会报错

  1. Session session = HibernateUtils.getCurrentSession();
  2. Transaction tr = session.beginTransaction();
  3. // 保存客户和联系人的数据
  4. Customer c1 = new Customer();
  5. c1.setCust_name("美美");
  6. // 创建2个联系人
  7. Linkman l1 = new Linkman();
  8. l1.setLkm_name("熊大");
  9. Linkman l2 = new Linkman();
  10. l2.setLkm_name("熊二");
  11. // 双向关联 begin
  12. c1.getLinkmans().add(l1);
  13. c1.getLinkmans().add(l2);
  14. l1.setCustomer(c1);
  15. l2.setCustomer(c1);
  16. // 双向关联 end
  17. // 保存数据
  18. session.save(c1);
  19. session.save(l1);
  20. session.save(l2);
  21. tr.commit();

级联操作

关键字:cascade

  1. /*cascade 取值*/
  2. none //不使用级联
  3. save-update //级联保存或更新
  4. delete //级联删除
  5. delete-orphan //孤儿删除.(注意:只能应用在一对多关系)
  6. all //除了delete-orphan的所有情况.(包含save-update delete)
  7. all-delete-orphan //包含了delete-orphan的所有情况.(包含save-update delete delete-orphan)

映射配置文件中配置

  1. <!--具有方向性:在'多方'设置,则对多方对象有效-->
  2. <many-to-one cascade="save-update,delete" />
  3. <!--例:-->
  4. <many-to-one name="customer" class="com.itheima.domain.Customer" column="lkm_cust_id" cascade="save-update,delete"/>

孤儿删除

    在解除了父子关系的时候.会将子方记录就直接删除。
一方映射配置文件
  1. <one-to-many class="com.itheima.domain.Linkman" cascade="delete-orphan"/>
集合中删除多方对象
  1. /**
  2. * 解除关系:从集合中删除联系人
  3. * 解除关系的同时也会将子方记录删除
  4. */
  5. Session session = HibernateUtils.getCurrentSession();
  6. Transaction tr = session.beginTransaction();
  7. // 先获取到客户
  8. Customer c1 = session.get(Customer.class, 1L);
  9. Linkman l1 = session.get(Linkman.class, 1L);
  10. // 解除
  11. c1.getLinkmans().remove(l1);
  12. tr.commit();

级联保存

一方实例
  1. <!--设置cascade="save-update"-->
  2. <one-to-many class="com.itheima.domain.Linkman" cascade="save-update"/>
  1. // 保存客户和联系人的数据
  2. /*
  3. * 一方和多方数据都会保存到数据库
  4. */
  5. Customer c1 = new Customer();
  6. c1.setCust_name("美美");
  7. // 创建2个联系人
  8. Linkman l1 = new Linkman();
  9. l1.setLkm_name("熊大");
  10. Linkman l2 = new Linkman();
  11. l2.setLkm_name("熊二");
  12. // 单向关联:一方关联多方
  13. c1.getLinkmans().add(l1);
  14. c1.getLinkmans().add(l2);
  15. // 保存数据
  16. session.save(c1);
多方实例
  1. <!--设置cascade="save-update"-->
  2. <many-to-one name="customer" class="com.itheima.domain.Customer" column="lkm_cust_id" cascade="save-update,delete"/>
  1. // 保存客户和联系人的数据
  2. /*
  3. * 一方和多方数据都会保存到数据库
  4. */
  5. Customer c1 = new Customer();
  6. c1.setCust_name("美美");
  7. // 创建2个联系人
  8. Linkman l1 = new Linkman();
  9. l1.setLkm_name("熊大");
  10. Linkman l2 = new Linkman();
  11. l2.setLkm_name("熊二");
  12. //单向关联:多方关联一方
  13. l1.setCustomer(c1);
  14. l2.setCustomer(c1);
  15. // 保存
  16. session.save(l1);

外键维护

关键字:inverse
重点:只有一方能使用

防止产生多余的SQL语句

实现步骤:想修改客户和联系人的关系,进行双向关联,双方都会维护外键,会产生多余的SQL语句。

分析原因:session的一级缓存中的快照机制,会让双方都更新数据库,产生了多余的SQL语句。

解决方法:'一方'放弃维护外键(在'一方'的映射配置文件<set>标签上配置一个inverse=”true”.true:放弃维护.false:不放弃.默认值是false)。
  1. <!--放弃维护外键-->
  2. <!--'一方'放弃维护外键后,将无法对外键进行操作-->
  3. <set name="linkmans" inverse="true">
  4. <key column="lkm_cust_id"/>
  5. <one-to-many class="com.itheima.domain.Linkman"/>
  6. </set>

多对多映射

重点:必须有一方放弃外键维护

基本操作(User to Role)

关系 表名 备注
多方 User 用户
多方 Role 角色

User配置

用户JavaBean配置
  1. public class User {
  2. //引入HashSet集合,并提供get、set方法
  3. //定义另一多方的集合roles
  4. private Set<Role> roles = new HashSet<Role>();
  5. private Long user_id;
  6. private String user_code;
  7. private String user_name;
  8. private String user_password;
  9. private String user_state;
  10. /*
  11. 省略……
  12. */
  13. }
用户的映射配置文件

User.hbm.xml

  1. <class name="com.itheima.domain.User" table="sys_user">
  2. <id name="user_id" column="user_id">
  3. <generator class="native"/>
  4. </id>
  5. <property name="user_code" column="user_code"/>
  6. <property name="user_name" column="user_name"/>
  7. <property name="user_password" column="user_password"/>
  8. <property name="user_state" column="user_state"/>
  9. <!--配置多对多
  10. name:JavaBean中的集合名称
  11. table:中间表名称(用于维护外键)
  12. -->
  13. <!--Hibernate会自动生成中间表sys_user_role-->
  14. <set name="roles" table="sys_user_role">
  15. <!-- 当前对象在中间表的外键的名称 -->
  16. <key column="user_id"/>
  17. <!--
  18. class 集合中存入对象,对象的全路径
  19. column 集合中对象在中间表的外键的名称
  20. -->
  21. <many-to-many class="com.itheima.domain.Role" column="role_id"/>
  22. </set>
  23. </class>

Role配置

角色JavaBean配置

Role.hbm.xml

  1. public class Role {
  2. //引入HashSet集合,并提供get、set方法
  3. //定义另一多方的集合users
  4. private Set<User> users = new HashSet<User>();
  5. private Long role_id;
  6. private String role_name;
  7. private String role_memo;
  8. /*
  9. 省略……
  10. */
  11. }
角色的映射配置文件
  1. <class name="com.itheima.domain.Role" table="sys_role">
  2. <id name="rid" column="rid">
  3. <generator class="native"/>
  4. </id>
  5. <property name="rname" column="rname"/>
  6. <!-- 多对多必须要有一方放弃外键的维护的 -->
  7. <set name="users" table="sys_user_role" inverse="true">
  8. <key column="rid"/>
  9. <many-to-many class="com.itheima.domain.User" column="uid"/>
  10. </set>
  11. </class>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注