Hibernate - 单向一对多关联关系映射
上篇博文描述了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 - 单向一对多关联关系映射相关推荐
- hibernate 的一对多关联关系映射配置
hibernate 是操作实体类: 表是一对多的关系,当创建这2个实体的时候 在一的一方定义一个多的一方的集合 在多的一方定义一个一的一方的对象 表是多对多的关系,当创建这2个实体的时候 在互相中都有 ...
- (转)Hibernate框架基础——一对多关联关系映射
http://blog.csdn.net/yerenyuan_pku/article/details/52746413 上一篇文章Hibernate框架基础--映射集合属性详细讲解的是值类型的集合(即 ...
- Hibernate的一对多关联关系(单向和双向)
在领域模型中,类与类之间最普遍的关系就是关联关系.在 UML 中,关联是有方向的.以 Customer 和 Order 为例:一个用户能发出多个订单, 而一个订单只能属于一个客户.从 Order 到 ...
- (八)Hibernate的一对多关联关系
一.概述 例如,以客户(Customer)和订单(Order)为例,一个客户能有多个订单,一个订单只能有一个客户. 从Customer到Order是一对多关联,在java类中的面向对象设计应该一个Cu ...
- hibernate单向一对多关联
2019独角兽企业重金招聘Python工程师标准>>> 有这样一个应用场景,有一张用户表(APM_USER),一张部门表(APM_DEPT).用户和部门之间的关系是多对一(many ...
- jpa单向一对多关联映射
如果在一的@OneToMany有@manyToOne则是双向一对多关联,如果在多的那面没有@manyToOne关联则是单向一对多关联 class和student是一对多的关系 表结构 student ...
- (经典)Hibernate的一对多关系映射(三)
一对多关系是表提出来的概念,两张表之间会存在这种,前提是有外键关联. 例如:省份和城市 如果设计类,怎样描述省份和城市之间的一对多关系 省份类里包含多个城市对象,使用 Set集合来描述 城市类里包含一 ...
- JPA中实现单向一对多的关联关系
场景 JPA入门简介与搭建HelloWorld(附代码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103473937 ...
- Hibernate关联关系映射实例速查
Hibernate关联关系映射实例速查 Hibernate的映射关系很多,也比较复杂,也很容易忘记.这个基本上占据了Hibernate学习的七成时间.熟悉这些映射模型,需要大量的实践才能掌握.下面是我 ...
最新文章
- 紧随Java 16,Spring Framework 5.3.5 发布:涵盖JDK 16的支持!
- css3+jQuery制作导航菜单(带动画效果)
- SpringBoot连接MQTT服务器时因ClintID重复导致频繁掉线重连
- 在服务器使用mysql_Linux服务器---使用mysql
- 实现option上下移动_js: 实现Select的option上下移动 | 学步园
- 部署WEB应用到云服务器时,出现的部分网页不能显示或者连接数据库问题。
- Kafka 详细配置参数说明
- 树莓派B+使用入门RPI库安装wringPi库安装
- 示范NTFS 卷上的流
- chmod 与fchmod函数
- 如何使用spring2.0
- oracle分页查询最高效,oracle 分页 高效写法总结
- 聚石塔,御城河接入,御河城安全整改demo
- Moment.js简单使用
- android 微博开发者平台,微博Android平台SDK文档V.pdf
- 2018年算法工程师薪酬报告出炉:平均年薪50.21万,点燃寒冬的一把火
- 企业钉钉群发送信息轮子
- chdir、fchdir 和 getcwd 函数
- 如何说宝贝才会听-处理情绪的工具
- 基于Springboot的人力资源管理系统的设计与实现