hibernate 一对多关联关系(具体分析)
在领域模型中, 类与类之间最普遍的关系就是关联关系.
- 以 Customer 和 Order 为例: 一个用户能发出多个订单, 而一个订单仅仅能属于一个客户. 从 Order 到 Customer 的关联是多对一关联; 而从 Customer 到 Order 是一对多关联
- 单向关联
- 双向关联
- 域模型: 从 Order 到 Customer 的多对一单向关联须要在Order 类中定义一个 Customer 属性, 而在 Customer 类中无需定义存放 Order 对象的集合属性
- 关系数据模型:ORDERS 表中的 CUSTOMER_ID 參照 CUSTOMER 表的主键
- 显然无法直接用 property 映射 customer 属性
- Hibernate 使用 <many-to-one> 元素来映射多对一关联关系
package com.atguigu.hibernate.entities.n21; public class Order { private Integer orderId;
private String orderName; private Customer customer; 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;
} public Customer getCustomer() {
return customer;
} public void setCustomer(Customer customer) {
this.customer = customer;
} }
Customer
package com.atguigu.hibernate.entities.n21; public class Customer { private Integer customerId;
private String customerName; 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;
} }
Customer.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.atguigu.hibernate.entities.n21.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" />
</property> </class> </hibernate-mapping>
Order.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.atguigu.hibernate.entities.n21"> <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" />
</property> <!--
映射多对一的关联关系。 使用 many-to-one 来映射多对一的关联关系
name: 多这一端关联的一那一端的属性的名字
class: 一那一端的属性相应的类名
column: 一那一端在多的一端相应的数据表中的外键的名字
-->
<many-to-one name="customer" class="Customer" column="CUSTOMER_ID"></many-to-one> </class>
</hibernate-mapping>
測试增删改查
package com.atguigu.hibernate.entities.n21; import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date; import org.hibernate.Hibernate;
import org.hibernate.LazyInitializationException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class HibernateTest { private SessionFactory sessionFactory;
private Session session;
private Transaction transaction; @Before
public void init(){
Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry =
new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry); session = sessionFactory.openSession();
transaction = session.beginTransaction();
} @After
public void destroy(){
transaction.commit();
session.close();
sessionFactory.close();
} @Test
public void testDelete(){
//在不设定级联关系的情况下, 且 1 这一端的对象有 n 的对象在引用, 不能直接删除 1 这一端的对象
Customer customer = (Customer) session.get(Customer.class, 1);
session.delete(customer);
} @Test
public void testUpdate(){
Order order = (Order) session.get(Order.class, 1);
order.getCustomer().setCustomerName("AAA");
} @Test
public void testMany2OneGet(){
//1. 若查询多的一端的一个对象, 则默认情况下, 仅仅查询了多的一端的对象. 而没有查询关联的
//1 的那一端的对象!
Order order = (Order) session.get(Order.class, 1);
System.out.println(order.getOrderName()); System.out.println(order.getCustomer().getClass().getName()); session.close(); //2. 在须要使用到关联的对象时, 才发送相应的 SQL 语句.
Customer customer = order.getCustomer();
System.out.println(customer.getCustomerName()); //3. 在查询 Customer 对象时, 由多的一端导航到 1 的一端时,
//若此时 session 已被关闭, 则默认情况下
//会发生 LazyInitializationException 异常 //4. 获取 Order 对象时, 默认情况下, 其关联的 Customer 对象是一个代理对象! } @Test
public void testMany2OneSave(){
Customer customer = new Customer();
customer.setCustomerName("BB"); Order order1 = new Order();
order1.setOrderName("ORDER-3"); Order order2 = new Order();
order2.setOrderName("ORDER-4"); //设定关联关系
order1.setCustomer(customer);
order2.setCustomer(customer); //运行 save 操作: 先插入 Customer, 再插入 Order, 3 条 INSERT
//先插入 1 的一端, 再插入 n 的一端, 仅仅有 INSERT 语句.
// session.save(customer);
//
// session.save(order1);
// session.save(order2); //先插入 Order, 再插入 Customer. 3 条 INSERT, 2 条 UPDATE
//先插入 n 的一端, 再插入 1 的一端, 会多出 UPDATE 语句!
//由于在插入多的一端时, 无法确定 1 的一端的外键值. 所以仅仅能等 1 的一端插入后, 再额外发送 UPDATE 语句.
//推荐先插入 1 的一端, 后插入 n 的一端
session.save(order1);
session.save(order2); session.save(customer);
} }
问题分析:
所以查不到 解决: 1 配双向 2,用原生sql 试试看 应该这种
hibernate 一对多关联关系(具体分析)的更多相关文章
- Hibernate一对多关联关系保存时的探究
在以前使用hibernate时,经常对保存存在关联关系的对象时,不确定是否能保存成功. 因此,特意对一对多关系的2个对象进行实践. 一.pojo类和配置文件的准备 这里有一点提前 ...
- hibernate一对多关联关系
想了几天,终于知道sql语句的发出问题.查了很多书,感觉都没有说清楚,有的还是错的.请看下面: <?xml version="1.0"?> <!DOCTYPE h ...
- Hibernate—— 一对多 和 多对多关联关系映射(xml和注解)总结(转载)
One to Many 映射关系 多对一单向外键关联(XML/Annotation) 一对多单向外键关联(XML/Annotation) 懒加载和积极加载 一对多双向外键关联(XML/Annotati ...
- Hibernate一对多(多对一)关联关系
上一篇博文总结了 Hibernate 的一对一的关联关系, 包括基于主键的单向一对一, 基于外键的单向一对一, 基于外键的双向一对一. 下面咱们说一下 Hibernate 的一对多关联关系. 其实一对 ...
- [原创]java WEB学习笔记82:Hibernate学习之路---映射 一对多关联关系,配置,CRUD方法测试及注意点
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Hibernate 一对多自身双向关联关系 用于类别表的实现
分类:一对多自身双向关联关系 Java持久化类: package com.hyy.hibernate.one_to_many.domain; import java.util.HashSet; imp ...
- 在Hibernate单向一对多关联关系中的org.hibernate.StaleStateException 异常。
具体异常如下: Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count fro ...
- (转)Hibernate框架基础——一对多关联关系映射
http://blog.csdn.net/yerenyuan_pku/article/details/52746413 上一篇文章Hibernate框架基础——映射集合属性详细讲解的是值类型的集合(即 ...
- 03.Hibernate一对多关联
前言:在域模型中,类与类之间最普遍的关系就是关联关系,在UML语言中关联关系是有方向的.在数据库中表与表之间也会有关联关系,本节介绍通过Hibernate映射一对多的关联关系,这是一种最普遍的关联关系 ...
随机推荐
- java提高篇(十一)-----代码块
在编程过程中我们可能会遇到如下这种形式的程序: public class Test { { //// } } 这种形式的程序段我们将其称之为代码块,所谓代码块就是用大括号({})将多行代码封装在一起, ...
- JAVA 公众微信的开放源码项目管理合作伙伴招募的版本号
大家好: jeecg开源社区.现在正在进行"JAVA 开放源码的版本号项目微信公共账号"工作,有兴趣的朋友一起參与. 截止时间:20140510 採用技术: 1. JE ...
- 数列的前N项之和
时间限制: 1 Sec 内存限制: 128 MB 提交: 393 解决: 309 [提交][状态][讨论版] 题目描述 有一分数序列: 2/1 3/2 5/3 8/5 13/8 21/13.... ...
- 10gocm->session5->数据库管理实验->GC资源管理器的资源消耗组介绍
<GC资源管理器> 官方文件:administrator's Guide->24 Using the Database Resource Manager 用法:在实际生产环境中使用 ...
- CentOS构造SNMP
<span style="font-size:14px;">本文介绍怎样在CentOS环境下配置一个简单的SNMP服务</span> 软件安装 切换到系统管 ...
- Python学习笔记12:标准库之对象序列化(pickle包,cPickle包)
计算机的内存中存储的是二进制的序列. 我们能够直接将某个对象所相应位置的数据抓取下来,转换成文本流 (这个过程叫做serialize),然后将文本流存入到文件里. 因为Python在创建对象时,要參考 ...
- angular input使用输入框filter格式化日期
最近使用angular日期选取器.只需要把所选的输出迄今input输入框,根据默认的假设,显示是在时间的形式的时间戳.不符合规定.需要格成一个特定的公式格公式.但input上ng-model不能直接对 ...
- nodeJs基础
Node.js 是一个基于Chrome JavaScript 执行时建立的一个平台, 用来方便地搭建高速的 易于扩展的网络应用· Node.js 借助事件驱动, 非堵塞I/O 模型变得轻量和高效, 很 ...
- C# WinForm中实现CheckBox全选反选功能
今天一群里有人问到这个功能,其实应该挺简单,但提问题的人问题的出发点并没有描述清楚.因此,一个简简单单的需求,就引起了群内热烈的讨论.下面看看这个功能如何去实现,先上效果: 下面直接上代码,请不要在意 ...
- SharePoint 2013 添加Ribbon菜单
原文:SharePoint 2013 添加Ribbon菜单 前言:今天,我们尝试一下添加SharePoint2013的Ribbon菜单,这个Ribbon菜单是由XML定义,JavaScript脚本来实 ...