什么是关联(association)

关联指的是类之间的引用关系。如果类A与类B关联,那么被引用的类B将被定义为类A的属性。例如:
  public class B{
        private String name;
        private List<A> bs = new arraylist();
      }
   public class A{
        private B b = new B;
        public A(){}
      }

关联的分类:关联可以分为一对一、一对多/多对一、多对多关联
   关联是有方向的

实例:

  以订单表t_hibernate_order与订单项表t_hibernate_order_item为例

1.实体映射文件

Order.hbm.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping>
  6. <class name="com.yuan.three.entity.Order" table="t_hibernate_order">
  7. <id name="orderId" type="java.lang.Integer" column="order_id">
  8. <generator class="increment" />
  9. </id>
  10. <property name="orderNo" type="java.lang.String" column="order_no">
  11. </property>
  12. <!-- 需要在映射文件中进行关联关系的维护 这里描述的是一对多的关系 -->
  13. <bag name="orderItems" cascade="save-update" inverse="true">
  14. <!-- 从表的外键 -->
  15. <key column="oid"></key>
  16. <!-- 查询从表的数据,然后形成list集合填充到orderItems属性中去 -->
  17. <one-to-many class="com.yuan.three.entity.OrderItem"/>
  18.  
  19. </bag>
  20. </class>
  21. </hibernate-mapping>

OrderItem.hbm.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping>
  6. <class name="com.yuan.three.entity.OrderItem" table="t_hibernate_order_item">
  7. <id name="orderItemId" type="java.lang.Integer" column="order_item_id">
  8. <generator class="increment" />
  9. </id>
  10. <property name="productId" type="java.lang.Integer" column="product_id">
  11. </property>
  12. <property name="quantity" type="java.lang.Integer" column="quantity">
  13. </property>
  14. <property name="oid" type="java.lang.Integer" column="oid" insert="false" update="false">
  15. </property>
  16. <!-- 需要在映射文件中进行关联关系的维护 这里描述的是多对一的关系 -->
  17. <!-- oid被重复映射报错:
  18. Repeated column in mapping for entity: com.yuan.three.entity.OrderItem column: oid (should be mapped with insert="false" update="false") -->
  19. <many-to-one name="order" class="com.yuan.three.entity.Order" column="oid"></many-to-one>
  20. </class>
  21. </hibernate-mapping>

2. 创建实体

Order.java

  1. package com.yuan.three.entity;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. public class Order {
  7.  
  8. private Integer orderId;
  9. private String orderNo;
  10. private List<OrderItem> orderItems = new ArrayList<>();
  11. private Integer initChildren = 1;//1代表开启懒加载,默认。0则代表关闭懒加载
  12.  
  13. public Integer getInitChildren() {
  14. return initChildren;
  15. }
  16. public void setInitChildren(Integer initChildren) {
  17. this.initChildren = initChildren;
  18. }
  19. public List<OrderItem> getOrderItems() {
  20. return orderItems;
  21. }
  22. public void setOrderItems(List<OrderItem> orderItems) {
  23. this.orderItems = orderItems;
  24. }
  25. public Integer getOrderId() {
  26. return orderId;
  27. }
  28. public void setOrderId(Integer orderId) {
  29. this.orderId = orderId;
  30. }
  31. public String getOrderNo() {
  32. return orderNo;
  33. }
  34. public void setOrderNo(String orderNo) {
  35. this.orderNo = orderNo;
  36. }
  37. @Override
  38. public String toString() {
  39. return "Order [orderId=" + orderId + ", orderNo=" + orderNo + ", orderItems=" + orderItems + "]";
  40. }
  41. public Order(Integer orderId, String orderNo) {
  42. super();
  43. this.orderId = orderId;
  44. this.orderNo = orderNo;
  45. }
  46. public Order() {
  47. super();
  48. // TODO Auto-generated constructor stub
  49. }
  50.  
  51. }

OrderItem.java

  1. package com.yuan.three.entity;
  2.  
  3. public class OrderItem {
  4.  
  5. private Integer orderItemId;
  6. private Integer productId;
  7. private Integer quantity;
  8. private Integer oid;
  9. private Order order;
  10.  
  11. public Order getOrder() {
  12. return order;
  13. }
  14. public void setOrder(Order order) {
  15. this.order = order;
  16. }
  17. public Integer getOrderItemId() {
  18. return orderItemId;
  19. }
  20. public void setOrderItemId(Integer orderItemId) {
  21. this.orderItemId = orderItemId;
  22. }
  23. public Integer getProductId() {
  24. return productId;
  25. }
  26. public void setProductId(Integer productId) {
  27. this.productId = productId;
  28. }
  29. public Integer getQuantity() {
  30. return quantity;
  31. }
  32. public void setQuantity(Integer quantity) {
  33. this.quantity = quantity;
  34. }
  35. public Integer getOid() {
  36. return oid;
  37. }
  38. public void setOid(Integer oid) {
  39. this.oid = oid;
  40. }
  41.  
  42. public OrderItem(Integer orderItemId, Integer productId, Integer quantity, Integer oid) {
  43. super();
  44. this.orderItemId = orderItemId;
  45. this.productId = productId;
  46. this.quantity = quantity;
  47. this.oid = oid;
  48. }
  49. public OrderItem() {
  50. super();
  51. // TODO Auto-generated constructor stub
  52. }
  53.  
  54. }

3.将实体映射文件配置到核心配置文件中hibernate.cfg.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-configuration PUBLIC
  3. "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  4. "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
  5. <hibernate-configuration>
  6. <session-factory>
  7. <!-- 1. 数据库相关 -->
  8. <property name="connection.username">root</property>
  9. <property name="connection.password">123</property>
  10. <property name="connection.url">jdbc:mysql://localhost:3306/xm_sc?useUnicode=true&amp;characterEncoding=UTF-8
  11. </property>
  12. <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
  13. <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
  14.  
  15. <!-- 配置本地事务(No CurrentSessionContext configured!) -->
  16. <property name="hibernate.current_session_context_class">thread</property>
  17.  
  18. <!-- 2. 调试相关 -->
  19. <property name="show_sql">true</property>
  20. <property name="format_sql">true</property>
  21.  
  22. <!-- 3. 添加实体映射文件 -->
  23. <mapping resource="com/yuan/one/entity/User.hbm.xml" />
  24. <!-- 主键生成策略 -->
  25. <mapping resource="com/yuan/two/Student.hbm.xml" />
  26. <mapping resource="com/yuan/two/Worker.hbm.xml"/>
  27. <!-- 一对多关联关系 -->
  28. <mapping resource="com/yuan/three/entity/Order.hbm.xml" />
  29. <mapping resource="com/yuan/three/entity/OrderItem.hbm.xml"/>
  30. </session-factory>
  31. </hibernate-configuration>

4.编写dao层

DemoDao.java

  1. package com.yuan.three.dao;
  2.  
  3. import java.util.List;
  4.  
  5. import org.hibernate.Hibernate;
  6. import org.hibernate.Session;
  7. import org.hibernate.Transaction;
  8.  
  9. import com.yuan.three.entity.Order;
  10. import com.yuan.three.entity.OrderItem;
  11. import com.yuan.two.util.SessionFactoryUtils;
  12.  
  13. public class DemoDao {
  14. /**
  15. * 为了测试关系型映射文件配置准确
  16. * 讲解insert=false,update=false的用途
  17. * @param order
  18. * @return
  19. */
  20. public Integer addOrder(Order order) {
  21. Session session = SessionFactoryUtils.openSession();
  22. Transaction transaction = session.beginTransaction();
  23. Integer oid = (Integer)session.save(order);
  24. transaction.commit();
  25. session.close();
  26. return oid;
  27. }
  28.  
  29. public Integer addOrderItem(OrderItem orderItem) {
  30. Session session = SessionFactoryUtils.openSession();
  31. Transaction transaction = session.beginTransaction();
  32. Integer otid = (Integer)session.save(orderItem);
  33. transaction.commit();
  34. session.close();
  35. return otid;
  36. }
  37.  
  38. /**
  39. * 为了讲解懒加载的问题(hibernate3.0后所有查询方式默认采用的是懒加载方式)
  40. * 1、查单个时存在问题,代理对象已经关闭
  41. * 2、查多个存在问题,有性能的问题
  42. * @param order
  43. * @return
  44. */
  45. public Order getOrder(Order order) {
  46. Session session = SessionFactoryUtils.openSession();
  47. Transaction transaction = session.beginTransaction();
  48. Order o = session.get(Order.class, order.getOrderId());
  49. if(o != null && new Integer(0).equals(order.getInitChildren())) {
  50. //0代表程序员想要关闭懒加载,也就意味着需要强制加载关联关系对象
  51. Hibernate.initialize(o.getOrderItems());
  52. // System.out.println(o.getOrderItems());
  53. }
  54. transaction.commit();
  55. session.close();
  56. return o;
  57. }
  58.  
  59. public List<Order> getOrderList() {
  60. Session session = SessionFactoryUtils.openSession();
  61. Transaction transaction = session.beginTransaction();
  62. List<Order> list = session.createQuery("from Order").list();
  63. transaction.commit();
  64. session.close();
  65. return list;
  66. }
  67.  
  68. /**
  69. * z主表的数据不能随便删除,得先删除从表中对应信息,才能删除主表的信息。
  70. * @param order
  71. */
  72. public void delOrder(Order order) {
  73. Session session = SessionFactoryUtils.openSession();
  74. Transaction transaction = session.beginTransaction();
  75. Order order2 = session.get(Order.class, order.getOrderId());
  76. for (OrderItem oi : order2.getOrderItems()) {
  77. session.delete(oi);
  78. }
  79. session.delete(order2);
  80. // session.delete(order);
  81. transaction.commit();
  82. session.close();
  83. }
  84. }

5.DemoDao进行junit测试

5.1 找到junit并进行测试

一:Ctrl+N输入junit   - -》  Next

二:Next

三:选择需要测试的DemoDao  - - 》  Finish

5.2 测试代码DemoDaoTest.java

  1. package com.yuan.three.dao;
  2.  
  3. import static org.junit.Assert.*;
  4.  
  5. import java.util.List;
  6.  
  7. import org.junit.Test;
  8.  
  9. import com.yuan.three.entity.Order;
  10. import com.yuan.three.entity.OrderItem;
  11.  
  12. public class DemoDaoTest {
  13.  
  14. private DemoDao demoDao = new DemoDao();
  15.  
  16. /**
  17. * 新增订单(单个对应多个订单项)
  18. */
  19. @Test
  20. public void testAddOrder() {
  21. Order order = new Order();
  22. order.setOrderNo("T226");
  23. OrderItem oi = null;
  24. for (int i = 0; i < 3; i++) {
  25. oi = new OrderItem();
  26. oi.setProductId(10+i);
  27. oi.setQuantity(20+i);
  28. oi.setOrder(order);
  29. order.getOrderItems().add(oi);
  30. }
  31. demoDao.addOrder(order);
  32. }
  33.  
  34. /**
  35. * 新增订单项(多个)
  36. */
  37. @Test
  38. public void testAddOrderItem() {
  39. Order order = new Order();
  40. order.setOrderId(5);
  41. OrderItem oi = null;
  42. for (int i = 0; i < 3; i++) {
  43. oi = new OrderItem();
  44. oi.setProductId(10+i);
  45. oi.setQuantity(20+i);
  46. oi.setOrder(order);
  47. order.getOrderItems().add(oi);
  48. demoDao.addOrderItem(oi);
  49. }
  50. }
  51.  
  52. /**
  53. * 查询单个
  54. * 重点:
  55. * 关于懒加载的问题
  56. * hibernate3之后出现的;
  57. * 错误信息:
  58. * failed to lazily initialize a collection of role:
  59. * com.yuan.three.entity.Order.orderItems,
  60. * could not initialize proxy - no Session
  61. *
  62. * orderNo数据来源于t_hibernate_order表
  63. * orderItems数据来源于t_hibernate_order_item表
  64. *
  65. * 因为两表有关联关系所以不可以分开查询,
  66. * 而hibernate默认的策略是不查询关联关系对应关联表数据的
  67. *
  68. * 处理方式:(第一种)
  69. * 在对应实体映射文件中的关联关系的维护中添加 lazy="false"
  70. * 如:<bag lazy="false" name="orderItems" cascade="save-update" inverse="true">
  71. */
  72. @Test
  73. public void testGetOrder() {
  74. Order order = new Order();
  75. order.setOrderId(10);
  76. //关闭懒加载
  77. order.setInitChildren(0);
  78. Order o = this.demoDao.getOrder(order);
  79. System.out.println(o.getOrderNo());
  80. System.out.println(o.getOrderItems());
  81. }
  82.  
  83. /**
  84. * 查询多个
  85. * 在查询单个中懒加载问题的解决方案
  86. * 会导致在查询多个的时候sql语句也会增多,
  87. * 当查询数据过多的时候导致代码性能变低
  88. *
  89. * 总:如果将懒加载的功能关闭,即:lazy=false,
  90. * 那么在查询多条订单数据的情况下是非常影响性能的
  91. *
  92. * 查单个需要关闭懒加载 目的是需要加载出关联表的数据
  93. * 查多个不能关闭懒加载 加载关联表的数据的查询次数过多
  94. *
  95. * 处理方式:(第二种)
  96. * 在一对多的实体类中添加属性是否打开懒加载
  97. *
  98. */
  99. @Test
  100. public void testGetOrderList() {
  101. List<Order> orderList = this.demoDao.getOrderList();
  102. for (Order order : orderList) {
  103. System.out.println(order.getOrderNo());
  104. // System.out.println(order.getOrderItems());
  105. }
  106. }
  107. /**
      * 删除订单,关联关系同时删除
      */
  108. @Test
  109. public void testDelOrder() {
  110. Order order = new Order();
  111. order.setOrderId(10);
  112. this.demoDao.delOrder(order);
  113. }
  114.  
  115. }

6. 测试结果

6.1 新增订单

t_hibernate_order  订单表

t_hibernate_order_item   订单项表

6.2新增订单项

t_hibernate_order_item   订单项表

6.3 查询单个

6.4 查询多个

6.5 删除订单

t_hibernate_order

t_hibernate_order_item

谢谢观看!!!

hibernate之关联关系一对多的更多相关文章

  1. Hibernate之关联关系(一对多)

    今日分享hibernate框架的简单关联关系 一:关联关系简介 1.1 什么是关联关系 关联指的是类之间的引用关系.如果类A与类B关联,那么被引用的类B将被定义为类A的属性. 例如: class B{ ...

  2. Hibernate在关于一对多,多对一双向关联映射

    [Hibernate]之关于一对多,多对一双向关联映射 因为一对多.和多对一的双向关联映射基本上一样,所以这里就一起写下来! Annotations配置 @Entity @Table(name=&qu ...

  3. Hibernate JPA 关联关系

    Hibernate JPA 关联关系: 使用cascade做级联操作(只有在满足数据库约束时才会生效): CascadeType.PERSIST: 级联保存,只有调用persist()方法,才会级联保 ...

  4. 框架之 hibernate之关联关系映射

    案例:完成CRM的联系人的保存操作 需求分析 1. 因为客户和联系人是一对多的关系,在有客户的情况下,完成联系人的添加保存操作 技术分析之Hibernate的关联关系映射之一对多映射(重点) 1. J ...

  5. (转)Hibernate关联映射——一对多(多对一)

    http://blog.csdn.net/yerenyuan_pku/article/details/70152173 Hibernate关联映射——一对多(多对一) 我们以客户(Customer)与 ...

  6. Hibernate的关联关系映射

    技术分析之Hibernate的关联关系映射之一对多映射(重点)        1. JavaWEB中一对多的设计及其建表原则        2. 先导入SQL的建表语句                 ...

  7. hibernate有关联关系删除子表时可能会报错,可以用个clear避免错误

    //清除子表数据 public SalesSet removeSalesSetDistributor(SalesSet salesSet ){ List<SalesSetDistributor& ...

  8. Hibernate之关联关系映射(一对一主键映射和一对一外键映射)

    1:Hibernate的关联关系映射的一对一外键映射: 1.1:第一首先引包,省略 1.2:第二创建实体类: 这里使用用户信息和身份证信息的关系,用户的主键编号既可以做身份证信息的主键又可以做身份证信 ...

  9. Hibernate 一对一关联关系

    双向一对一关联关系: 域模型: 例如,部门只有一个部门经理,一个经理也只能管理一个部门.即,Department 中有一个Manager的引用,Manager 中又有一个Department 的引用. ...

随机推荐

  1. Tomcat是一个Servlet容器?

    "Tomcat是一个Servlet容器",这句话对于2019年的程序员应该是耳熟能详的. 单纯的思考一下这句话,我们可以抽象出来这么一段代码: class Tomcat { Lis ...

  2. 关于MSVCR100.dll、MSVCR100d.dll、Msvcp100.dll、abort()R6010等故障模块排查及解决方法

    一.常见故障介绍 最近在开发相机项目(项目细节由于公司保密就不介绍了),程序运行5个来月以来首次出现msvcr100.dll故障等问题,于是乎开始了分析之路,按照度娘上的一顿操作,期间也是出现了各种不 ...

  3. Linux 中的 ~/. 表示的意思

    在Linux中, ~ 表示用户的目录, 如用户名是Gavin, 那么~/表示  /home/Gavin 所以~/. 表示 用户目录下的隐藏文件. 扩展: 若以用户身份登录 ~ 表示 /home  目录 ...

  4. 「CTS2019」珍珠

    「CTS2019」珍珠 解题思路 看了好多博客才会,问题即要求有多少种方案满足数量为奇数的变量数 \(\leq n-2m\).考虑容斥,令 \(F(k)\) 为恰好有 \(n\) 个变量数量为奇数的方 ...

  5. mpvue + vant + flyio 小程序项目总结

    vant 的使用 我开始是 npm 导入,然后 import,使用不了. 找了各种方法,最后还是下载文件,然后找到 dist 文件夹,复制到项目里,我是放在 static 文件夹,文件名 dist 重 ...

  6. SpringBoot 多数据库支持:

    SpringBoot 多数据库支持: springboot2.0+mybatis多数据源集成 https://www.cnblogs.com/cdblogs/p/9275883.html Spring ...

  7. sql 数据库实时增量更新

    ---一下sql可以添加到作业中每秒执行一次   数据过多会消耗性能 --数据表如下,其中字段pid mid time price_type是一个组合主键--pid mid time price pr ...

  8. 面试总结 转发(CSDN 博主)

    1 https://blog.csdn.net/jackfrued/article/details/44921941 2 https://blog.csdn.net/jackfrued/article ...

  9. 常用的MySQL命令

    1.新建数据库: create database person; 2.使用数据库 use person: 3.创建一个表格 create table student ( id int(10) not ...

  10. js --桥接模式

    定义: 将抽象部分与它的实现部分分离,使他们都可以独立的变化. 也就是说,桥接模式里面有两个角色: - 扩充抽象类 - 具体实现类 在写桥接模式之前,想在写一下关于抽象的理解.我觉得抽象这个概念过于抽 ...