hibernate 双向1对多
1:
还是用客户Customer和订单Order来解释:
“一对多”的物理意义:一个客户可以有多个订单,某个订单只能归宿于一个客户。
“双向”的物理意义:客户知道自己有哪些订单,订单也知道自己归宿于哪个客户。也就是说,通过客户对象可以检索到其拥有哪些订单;同时,通过订单也可以查找到其对应的客户信息。这是符合我们业务逻辑需求。
1的1方
<set name="orders" table="ORDERS">
<key column="customer_Id"></key>
<one-to-many class="Order"/>
</set>
多的1方
<many-to-one name="customer" class="Customer" column="customer_Id"></many-to-one>
例子:
1的一方:
package com.hibernate.n21.both; import java.util.HashSet;
import java.util.Set; public class Customer {
private Integer customerId;
private String customerName;
//双向1对多 在1的1方加一个set集合
//需要把集合进行初始化。可防止空指针异常。
private Set<Order> orders =new HashSet<Order>(); public 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;
} }
1的一方的配置文件:
<?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.hibernate.n21.both"> <class name="Customer" table="customer"> <id name="customerId" type="java.lang.Integer">
<column name="customer_Id" />
<!-- 指定主键的生成方式, native: 使用数据库本地方式 -->
<generator class="native" />
</id> <property name="customerName"
type="java.lang.String" column="customer_Name" >
</property> <set name="orders" table="ORDERS">
<key column="customer_Id"></key>
<one-to-many class="Order"/>
</set> </class> </hibernate-mapping>
多的一方:
package com.hibernate.n21.both; 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;
} }
<?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.hibernate.n21.both"> <class name="Order" table="orders" > <id name="orderId" type="java.lang.Integer">
<column name="order_Id" />
<!-- 指定主键的生成方式, native: 使用数据库本地方式 -->
<generator class="native" />
</id> <property name="orderName"
type="java.lang.String" column="order_Name" >
</property> <!-- 映射n-1的关联关系 -->
<many-to-one name="customer" class="Customer" column="customer_Id"></many-to-one>
</class> </hibernate-mapping>
测试:
保存save():
@org.junit.Test
public void testN21Save(){
Customer customer=new Customer();
customer.setCustomerName("AA");
Order order1 =new Order();
order1.setOrderName("order-1");
Order order2 =new Order();
order2.setOrderName("order-2");
//会出现3个insert。2个update。 因为 1 的一端和 n 的一端都维护关联关系. 所以会多出 UPDATE
//可以在 1 的一端的 set 节点指定 inverse=true, 来使 1 的一端放弃维护关联关系!
//建议设定 set 的 inverse=true, 建议先插入 1 的一端, 后插入多的一端
inverse 相反的。反转。反转维护的方向。
inverse="true"。就是让1的一方放弃维护关系。因为我们都可以记住习大大。但是习大大不可能全记得我们
//好处是不会多出 UPDATE 语句
//设置关联关系。就是给多的一方设置外键
order1.setCustomer(customer);
order2.setCustomer(customer);
customer.getOrders().add(order1);
customer.getOrders().add(order2); session.save(customer);
session.save(order1);
session.save(order2);
}
查询:
@org.junit.Test
public void testGet(){
Customer customer=(Customer) session.get(Customer.class, 1);
System.out.println(customer.getCustomerName());
}
只显示Customer。没有出现set集合的内容。
@org.junit.Test
public void testGet(){
Customer customer=(Customer) session.get(Customer.class, 1);
System.out.println(customer.getCustomerName());
//2:class org.hibernate.collection.internal.PersistentSet 返回的hibernate内置的集合类型。
//这个类型具有延迟加载和存放代理对象的功能。
System.out.println(customer.getOrders().getClass()); }
@org.junit.Test
public void testGet(){
Customer customer=(Customer) session.get(Customer.class, 1);
System.out.println(customer.getCustomerName());
//class org.hibernate.collection.internal.PersistentSet 返回的hibernate内置的集合类型。
//这个类型具有延迟加载和存放代理对象的功能。
System.out.println(customer.getOrders().getClass());
//3:在查询完customer后就把session关闭。会出现懒加载异常。
session.close();
System.out.println(customer.getOrders().size());
}
4:在需要使用集合中元素的时候进行初始化。
删除:
@org.junit.Test
public void testDelete(){
Customer customer=(Customer) session.get(Customer.class, 1);
session.delete(customer);
}
直接删除的话会报错。
在配置文件中的set集合。设置cascade属性。
这是级联删除。就是只要多的一方的外键是1的主键的。删除1。对应的多的全部删除掉。
<set name="orders" table="ORDERS" inverse="true" cascade="delete">
cascade="delete-orphan":删除孤儿。解除关联关系。把多的外键为1主键的都删除掉。因为解除关系了。变成孤儿了。
save-update 级联保存。就是不用写session.save(order);
order-by属性:里面是数据库中的字段名。不是类的属性名。
hibernate 双向1对多的更多相关文章
- Hibernate双向多对多关联
一.配置双向多对多关联 以Project类(项目)和Emp类(员工)为例: 1.创建Project类,并需要定义集合类型的Emp属性 public class Project { //编号 priva ...
- 注解:【无连接表的】Hibernate双向1->N关联
Person与Address关联:双向1->N,[无连接表的],推荐使用 #由N端控制关联关系 #对于指定了mappedBy属性的@OneToMany,@ManyToMany,@OneToOne ...
- Hibernate双向多对多对象关系模型映射
1 双向many-to-many 业务模型: 描述员工和项目 一个员工同时可以参与多个项目 一个项目中可以包含多个员工 分析:数据库的数据模型,通过中间关系表,建立两个one-to-many构成man ...
- hibernate 双向n-n
领域模型: 关系数据模型 双向 n-n 关联须要两端都使用集合属性 双向n-n关联必须使用连接表 集合属性应添加 key 子元素用以映射外键列, 集合元素里还应添加many-to-many子元素关联实 ...
- hibernate 双向 1-n(具体分析)
双向 1-n 与 双向 n-1 是全然同样的两种情形 双向 1-n 须要在 1 的一端能够訪问 n 的一端, 反之依旧. 域模型:从 Order 到 Customer 的多对一双向关联须要在Order ...
- hibernate双向一对多映射
双向多对一 :Customer类------------>一的一端 Order类----------->多的一端 Customer类:(省略set().get()和构造方法) priv ...
- hibernate双向关联
双向关联中最好的设置是一端为inverse=true,一端为inverse=false. falses维护,true不维护,设置多的一方维护(false) inverse属性就是用来规定是由谁来维护这 ...
- 注解:【基于外键的】Hibernate双向1->1关联
Person与Address关联:双向1->1,[基于外键的]. #主表不应该控制关联关系.(否则会导致生成额外的update语句,从而导致性能下降), #因此主表对应的实体中使用@OneToO ...
- 注解:Hibernate双向N->N关联(两端都控制关联关系)
Person与Address关联:双向N->N,[连接表必须有],两端都控制关联关系 #需要说明的是:如果程序希望某一端放弃控制关联关系,则可以在这一段的@ManyToMany注解中指定mapp ...
随机推荐
- FS,FT,DFS,DTFT,DFT,FFT的联系和区别 数字信号处理
DCT变换的原理及算法 文库介绍 对于初学数字信号处理(DSP)的人来说,这几种变换是最为头疼的,它们是数字信号处理的理论基础,贯穿整个信号的处理. 学习过<高等数学>和<信号与系统 ...
- S1 Python 基础
定义规范 声明变量 name = "Alex Li" 变量定义规则 变量名只能是 字母.数字或下划线的任意组合 变量名的第一个字符不能是数字 以下关键字不能声明为变量名['and' ...
- 攻防世界 WEB篇
0x01 ics-06 查看源码发现:index.php 一开始直接用sqlmap跑了下没有发现注入,然后用brupsuite爆破参数 0x02 NewsCenter SQL注入中的POST注入,查阅 ...
- 修改element中v-loading的自定义图片
/*elementui loading css 覆盖 开始*/ .el-loading-spinner .circular{ width: 42px; height: 42px; animation: ...
- 最强DE战斗力
最强DE战斗力 时间限制: 1 Sec 内存限制: 128 MB提交: 40 解决: 14[提交][状态] 题目描述 春秋战国时期,赵国地大物博,资源非常丰富,人民安居乐业.但许多国家对它虎视眈眈 ...
- 运行python不报错,运行pip报错
Fatal error in launcher: Unable to create process using '""c:\program files (x86)\python36 ...
- 2018-2019-2 实验四 Android程序设计
实验要求 参考Android开发简易教程 完成云班课中的检查点,也可以先完成实验报告,直接提交.注意不能只有截图,要有知识点,原理,遇到的问题和解决过程等说明.实验报告中一个检查点要有多张截图. 发表 ...
- Android实战技巧:Dialog (转)
转:http://blog.csdn.net/hitlion2008/article/details/7567549#t0 Dialog是任何系统都必须有的一个控件,作为辅助窗口,用于显示一些消息,或 ...
- python rpy2,tkinter安装问题解决
windows系统下 在python中直接pip install rpy2时,会出错,没仔细看错误,直接下载了whl文件(https://www.lfd.uci.edu/~gohlke/pythonl ...
- Linux系统CPU占用率较高问题排查思路
作为 Linux 运维工程师,在日常工作中我们会遇到 Linux服务器上出现CPU负载达到100%居高不下的情况,如果CPU 持续跑高,则会影响业务系统的正常运行,带来企业损失. 很多运维的同学遇到这 ...