上篇博文描述了Hibernate - 单向多对一关联关系映射,本篇博文继续学习单向一对多关系映射。

这里Customer:Order= 1:N,外键保存在Order表中。

【1】修改Customer和Order

Customer修改如下:

public class Customer {private Integer customerId;private String customerName;private Set<Order> orders;//拥有属性orderspublic Set<Order> getOrders() {return orders;}public void setOrders(Set<Order> orders) {this.orders = orders;}public Integer getCustomerId() {return customerId;}public void setCustomerId(Integer customerId) {this.customerId = customerId;}public String getCustomerName() {return customerName;}public void setCustomerName(String customerName) {this.customerName = customerName;}@Overridepublic String toString() {return "Customer [customerId=" + customerId + ", customerName=" + customerName + ", orders=" + orders + "]";}}

Customer.hbm.xml修改如下:

<hibernate-mapping package="com.jane.model"><class name="Customer" table="CUSTOMERS"><id name="customerId" type="java.lang.Integer"><column name="CUSTOMER_ID" /><generator class="native" /></id><property name="customerName" type="java.lang.String"><column name="CUSTOMER_NAME" default="null" /></property><!--name="orders"表示一的一端拥有多的那端的属性;key节点中属性column="customer_id"表示外键(数据库多的一端拥有的)--><set name="orders" table="ORDERS"><key column="customer_id"></key><one-to-many class="Order"/></set></class>
</hibernate-mapping>

<key>元素设定本持久化类在Set对应表中的外键列名。如上值Customer类在ORDERS表中的外键列名–customer_id。

Order修改如下:

public class Order {private Integer orderId;private String orderName;public Integer getOrderId() {return orderId;}public void setOrderId(Integer orderId) {this.orderId = orderId;}public String getOrderName() {return orderName;}public void setOrderName(String orderName) {this.orderName = orderName;}@Overridepublic String toString() {return "Order [orderId=" + orderId + ", orderName=" + orderName+"]";}}

Order.hbm.xml如下:

<hibernate-mapping package="com.jane.model"><class name="Order" table="ORDERS"><id name="orderId" type="java.lang.Integer"><column name="ORDER_ID" /><generator class="native" /></id><property name="orderName" type="java.lang.String"><column name="ORDER_NAME" default="null" /></property></class>
</hibernate-mapping>

生成的数据库表结构如下所示:

//Customers表
CREATE TABLE `customers` (`CUSTOMER_ID` int(11) NOT NULL AUTO_INCREMENT,`CUSTOMER_NAME` varchar(255) DEFAULT NULL,PRIMARY KEY (`CUSTOMER_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;//Orders表
CREATE TABLE `orders` (`ORDER_ID` int(11) NOT NULL AUTO_INCREMENT,`ORDER_NAME` varchar(255) DEFAULT NULL,`customer_id` int(11) DEFAULT NULL,PRIMARY KEY (`ORDER_ID`),KEY `FK1nbewmmir6psft27yfvvmwpfg` (`customer_id`),CONSTRAINT `FK1nbewmmir6psft27yfvvmwpfg` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`CUSTOMER_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

可以发现,无论是多对一还是一对多,外键都是多的一端数据表所持有。

单向多对一中,以多的一端为主,在多的一端xml中使用<many-to-one/>进行配置。
单向一对多中,以一的一端为主,在一的一端xml中使用<one-to-many/>进行配置。


【2】代码测试

① 单向一对多持久化

和单向多对一持久化不同的是,单向 1-n 关联关系执行保存时, 一定会多出 UPDATE 语句。因为 n 的一端在插入时不会同时插入外键列。

 @Testpublic void testOneToManySave(){Customer customer = new Customer();customer.setCustomerName("AAA");customer.setOrders(new HashSet<>());Order order1 = new Order();order1.setOrderName("O-JJ-1");Order order2 = new Order();order2.setOrderName("O-JJ-2");System.out.println(customer);//建立关联关系customer.getOrders().add(order1);customer.getOrders().add(order2);session.save(customer);session.save(order1);session.save(order2);}

测试结果如下:

Hibernate: insert intoCUSTOMERS(CUSTOMER_NAME) values(?)
Hibernate: insert intoORDERS(ORDER_NAME) values(?)
Hibernate: insert intoORDERS(ORDER_NAME) values(?)
Hibernate: updateORDERS setcustomer_id=? whereORDER_ID=?
Hibernate: updateORDERS setcustomer_id=? whereORDER_ID=?

② 单向一对多获取对象

默认对关联的多的一方使用懒加载的加载策略,只有在使用的时候才会进行查询。

测试代码如下:

 @Testpublic void testOneToManyGet(){Customer customer = session.get(Customer.class, 1);System.out.println(customer);System.out.println(customer.getOrders().size());}

测试结果如下:

Hibernate: selectcustomer0_.CUSTOMER_ID as CUSTOMER1_0_0_,customer0_.CUSTOMER_NAME as CUSTOMER2_0_0_ fromCUSTOMERS customer0_ wherecustomer0_.CUSTOMER_ID=?
Hibernate: selectorders0_.customer_id as customer3_2_0_,orders0_.ORDER_ID as ORDER_ID1_2_0_,orders0_.ORDER_ID as ORDER_ID1_2_1_,orders0_.ORDER_NAME as ORDER_NA2_2_1_ fromORDERS orders0_ whereorders0_.customer_id=?
Customer [customerId=1, customerName=AAA, orders=[Order [orderId=1, orderName=O-JJ-1], Order [orderId=2, orderName=O-JJ-2]]]
2

③ 单向一对多更新操作

代码如下:

 @Testpublic void testUpdate(){Customer customer = session.get(Customer.class, 1);customer.getOrders().iterator().next().setOrderName("O-XXX-10");}

测试结果如下:

Hibernate: selectcustomer0_.CUSTOMER_ID as CUSTOMER1_0_0_,customer0_.CUSTOMER_NAME as CUSTOMER2_0_0_ fromCUSTOMERS customer0_ wherecustomer0_.CUSTOMER_ID=?
Hibernate: selectorders0_.customer_id as customer3_2_0_,orders0_.ORDER_ID as ORDER_ID1_2_0_,orders0_.ORDER_ID as ORDER_ID1_2_1_,orders0_.ORDER_NAME as ORDER_NA2_2_1_ fromORDERS orders0_ whereorders0_.customer_id=?
Hibernate: updateORDERS setORDER_NAME=? whereORDER_ID=?

单独更新CustomerName如下:

 @Testpublic void testUpdate(){Customer customer = session.get(Customer.class, 1);customer.setCustomerName("CC");System.out.println(customer.getCustomerName());System.out.println(customer);}

测试结果如下:

Hibernate: selectcustomer0_.CUSTOMER_ID as CUSTOMER1_0_0_,customer0_.CUSTOMER_NAME as CUSTOMER2_0_0_ fromCUSTOMERS customer0_ wherecustomer0_.CUSTOMER_ID=?
CC
Hibernate: selectorders0_.customer_id as customer3_2_0_,orders0_.ORDER_ID as ORDER_ID1_2_0_,orders0_.ORDER_ID as ORDER_ID1_2_1_,orders0_.ORDER_NAME as ORDER_NA2_2_1_ fromORDERS orders0_ whereorders0_.customer_id=?
Customer [customerId=1, customerName=CC, orders=[Order [orderId=1, orderName=O-XXX-10], Order [orderId=2, orderName=O-JJ-2]]]
Hibernate: updateCUSTOMERS setCUSTOMER_NAME=? whereCUSTOMER_ID=?

④ 单向一对多删除操作

默认情况下, 若删除 1 的一端, 则会先把关联的 n 的一端的外键置空, 然后进行删除。

测试代码如下:

 @Testpublic void testOneToManyDel(){Customer customer = session.get(Customer.class,1);session.delete(customer);}

测试结果如下:

//先查询
Hibernate: selectcustomer0_.CUSTOMER_ID as CUSTOMER1_0_0_,customer0_.CUSTOMER_NAME as CUSTOMER2_0_0_ fromCUSTOMERS customer0_ wherecustomer0_.CUSTOMER_ID=?
//更新Order表的外键Customer_ID 为null
Hibernate: updateORDERS setcustomer_id=null wherecustomer_id=?//删除Customers
Hibernate: delete fromCUSTOMERS whereCUSTOMER_ID=?

综上可知,只有在持久化操作和删除操作时,单向一对多和单向多对一有所不同,在查找和更新时没有什么区别。

博文是基于XML进行讲解,那么注解版的如何使用呢?

参考博文:注解版的单向一对多

Hibernate - 单向一对多关联关系映射相关推荐

  1. hibernate 的一对多关联关系映射配置

    hibernate 是操作实体类: 表是一对多的关系,当创建这2个实体的时候 在一的一方定义一个多的一方的集合 在多的一方定义一个一的一方的对象 表是多对多的关系,当创建这2个实体的时候 在互相中都有 ...

  2. (转)Hibernate框架基础——一对多关联关系映射

    http://blog.csdn.net/yerenyuan_pku/article/details/52746413 上一篇文章Hibernate框架基础--映射集合属性详细讲解的是值类型的集合(即 ...

  3. Hibernate的一对多关联关系(单向和双向)

    在领域模型中,类与类之间最普遍的关系就是关联关系.在 UML 中,关联是有方向的.以 Customer 和 Order 为例:一个用户能发出多个订单, 而一个订单只能属于一个客户.从 Order 到 ...

  4. (八)Hibernate的一对多关联关系

    一.概述 例如,以客户(Customer)和订单(Order)为例,一个客户能有多个订单,一个订单只能有一个客户. 从Customer到Order是一对多关联,在java类中的面向对象设计应该一个Cu ...

  5. hibernate单向一对多关联

    2019独角兽企业重金招聘Python工程师标准>>> 有这样一个应用场景,有一张用户表(APM_USER),一张部门表(APM_DEPT).用户和部门之间的关系是多对一(many ...

  6. jpa单向一对多关联映射

    如果在一的@OneToMany有@manyToOne则是双向一对多关联,如果在多的那面没有@manyToOne关联则是单向一对多关联 class和student是一对多的关系 表结构 student ...

  7. (经典)Hibernate的一对多关系映射(三)

    一对多关系是表提出来的概念,两张表之间会存在这种,前提是有外键关联. 例如:省份和城市 如果设计类,怎样描述省份和城市之间的一对多关系 省份类里包含多个城市对象,使用 Set集合来描述 城市类里包含一 ...

  8. JPA中实现单向一对多的关联关系

    场景 JPA入门简介与搭建HelloWorld(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103473937 ...

  9. Hibernate关联关系映射实例速查

    Hibernate关联关系映射实例速查 Hibernate的映射关系很多,也比较复杂,也很容易忘记.这个基本上占据了Hibernate学习的七成时间.熟悉这些映射模型,需要大量的实践才能掌握.下面是我 ...

最新文章

  1. 紧随Java 16,Spring Framework 5.3.5 发布:涵盖JDK 16的支持!
  2. css3+jQuery制作导航菜单(带动画效果)
  3. SpringBoot连接MQTT服务器时因ClintID重复导致频繁掉线重连
  4. 在服务器使用mysql_Linux服务器---使用mysql
  5. 实现option上下移动_js: 实现Select的option上下移动 | 学步园
  6. 部署WEB应用到云服务器时,出现的部分网页不能显示或者连接数据库问题。
  7. Kafka 详细配置参数说明
  8. 树莓派B+使用入门RPI库安装wringPi库安装
  9. 示范NTFS 卷上的流
  10. chmod 与fchmod函数
  11. 如何使用spring2.0
  12. oracle分页查询最高效,oracle 分页 高效写法总结
  13. 聚石塔,御城河接入,御河城安全整改demo
  14. Moment.js简单使用
  15. android 微博开发者平台,微博Android平台SDK文档V.pdf
  16. 2018年算法工程师薪酬报告出炉:平均年薪50.21万,点燃寒冬的一把火
  17. 企业钉钉群发送信息轮子
  18. chdir、fchdir 和 getcwd 函数
  19. 如何说宝贝才会听-处理情绪的工具
  20. 基于Springboot的人力资源管理系统的设计与实现

热门文章

  1. MySQL复制与高可用水平扩展架构实战
  2. 浏览器的同源策略和跨域请求_学习版
  3. 使用RenderControl方法实现动态加载用户控件
  4. 工业开关电源电路图 15W电源mw电路图 25W电源
  5. 分数乘法计算机题,分数乘法练习题
  6. linux 跨进程读取内存,Android之Linux跨进程通信的方式
  7. 不同矫正批次效应方法的比较
  8. 【运维面试】秘不外宣的运维项目准备技巧二
  9. SEO们,停下互点和伪原创,进来看下
  10. 知识分享|To B产品的帮助中心页面制作方法