示例代码:

Customer.java

package cn.itcast.many2onedouble;

import java.util.HashSet;
import java.util.Set;
/**
* 一的一端
*/
@SuppressWarnings("serial")
public class Customer implements java.io.Serializable { private Integer id;
private String name;
//一个客户对应多个订单
private Set<Order> orderes=new HashSet<Order>(0); public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Order> getOrderes() {
return orderes;
}
public void setOrderes(Set<Order> orderes) {
this.orderes = orderes;
} }

Order.java

package cn.itcast.many2onedouble;

/**
* 多的一端
*/
public class Order {
private Integer id;
private String orderNumber;
private Double price; //建立订单到客户的多一关联
private Customer customer; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getOrderNumber() {
return orderNumber;
} public void setOrderNumber(String orderNumber) {
this.orderNumber = orderNumber;
} public Double getPrice() {
return price;
} public void setPrice(Double price) {
this.price = price;
} public Customer getCustomer() {
return customer;
} public void setCustomer(Customer customer) {
this.customer = customer;
} }

App.java

package cn.itcast.many2onedouble;

import java.util.Iterator;
import java.util.Set; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test; public class App {
private static SessionFactory sf=null; static{
Configuration config=new Configuration();
config.configure("cn/itcast/many2onedouble/hibernate.cfg.xml");
config.addClass(Customer.class);
config.addClass(Order.class);
sf=config.buildSessionFactory();
} //知识点6:保存客户和订单(客户和订单建立双向关联)
@Test
public void saveCustomerAndOrder(){
Session session=sf.openSession();
Transaction tx=session.beginTransaction(); Customer c=new Customer();
c.setName("关羽"); Order o=new Order();
o.setOrderNumber("NO1");
o.setPrice(12d); //建立订单和客户的双向关联 //建立订单和客户的关联
o.setCustomer(c); //建立客户和订单的关联
c.getOrderes().add(o); //保存客户
session.save(c); //保存订单
session.save(o); tx.commit();
session.close();
} //知识点7:保存客户和不保存订单
@Test
public void saveCustomerAndOrderCase(){
Session session=sf.openSession();
Transaction tx=session.beginTransaction(); Customer c=new Customer();
c.setName("飞"); Order o=new Order();
o.setOrderNumber("NO2");
o.setPrice(12d); //建立订单和客户的双向关联 //建立订单和客户的关联
o.setCustomer(c); //建立客户和订单的关联
c.getOrderes().add(o); //保存客户
session.save(c); //保存订单
//session.save(o); tx.commit();
session.close();
} //知识点8:查询客户和订单
@Test
public void getCustomer(){
Session session=sf.openSession();
Transaction tx=session.beginTransaction(); //从一的一端开始查询
Customer c=(Customer)session.get(Customer.class, 2);
System.out.println(c.getId()+" "+c.getName()); Set<Order> set=c.getOrderes();
Iterator<Order> it=set.iterator();
while(it.hasNext()){
Order o=it.next();
System.out.println(o.getId()+" "+o.getOrderNumber()+" "+o.getPrice());
} tx.commit();
session.close();
} //知识点9:对象导航
@Test
public void objectRelation(){
Session session=sf.openSession();
Transaction tx=session.beginTransaction(); Order o1=new Order();
o1.setOrderNumber("NO1");
o1.setPrice(23d); Order o2=new Order();
o2.setOrderNumber("NO2");
o2.setPrice(23d); Order o3=new Order();
o3.setOrderNumber("NO3");
o3.setPrice(23d); Customer c=new Customer();
c.setName("关羽"); //order1关联到customer 而customer没有关联到order1 --单向关联
o1.setCustomer(c); //customer关联到order2 order3 而order2 order3 没有关联到customer 单向关联
c.getOrderes().add(o2);
c.getOrderes().add(o3); //保存o1
session.save(o1);
//保存c
//session.save(c); //保存o2
//session.save(o2); tx.commit();
session.close();
} /*
* 知识点10:保持程序的健壮性
*/
@Test
public void testDouleRaletion(){
Session session=sf.openSession();
Transaction tx=session.beginTransaction(); Customer c=new Customer();
c.setName("飞"); Order o=new Order();
o.setOrderNumber("NO2");
o.setPrice(12d);
/************************************************************************************************************/
//建立订单和客户的双向关联
//建立订单和客户的关联
o.setCustomer(c); //建立客户和订单的关联
c.getOrderes().add(o);
/************************************************************************************************************/
//保存客户
session.save(c); //保存订单
session.save(o); tx.commit();
session.close();
} /************************************************************************************************************/ //知识点11:订单变更客户
//更改订单表id=6的customer_id=3更改为4
@Test
public void changeOrderHander(){
Session session=sf.openSession();
Transaction tx=session.beginTransaction(); //获取id=6号的订单,查询的订单和订单关联的客户放置在sessioln的一级缓存中,同时还产生一份快照
Order o6=(Order)session.get(Order.class, 6); //获取id=4客户
Customer c4=(Customer)session.get(Customer.class, 4);
/**************************************************************************************/
//建立关联关系
/*
* 在set标签中配置inverse="true",则多的一端说了算,一的一端说了不算
* 当缓存中的数据发生变化时
* * 如果多的一端关联的客户发生变化,此时执行update语句
* * 如果一的一端对应的订单集合中的订单发生变化时,
* 因为一的一端说了不算,所以不会按照订单集合中订单的变化执行update语句
*/ //让6号订单和4号客户关联
o6.setCustomer(c4); //有update语句 //在4号客户对应的订单集合中加入6号订单
c4.getOrderes().add(o6); //没有update语句,加和不加没有影响,但建议还是加上
/**************************************************************************************/ tx.commit();
session.close();
} /*
* 知识点12:解除关联关系
* 解除6号订单和3号客户的关联
*/
@Test
public void removeRelation(){
Session session=sf.openSession();
Transaction tx=session.beginTransaction(); //获取id=6号的订单,查询的订单和订单关联的客户放置在sessioln的一级缓存中,同时还产生一份快照
Order o6=(Order)session.get(Order.class, 6); //获取id=3客户
Customer c3=(Customer)session.get(Customer.class, 3); //解除双方的关联关系
o6.setCustomer(null);
c3.getOrderes().remove(o6); tx.commit();
session.close();
} /*
* 知识点13:级联删除删除1号客户的同时,删除1号客户所关联的订单
*/
@Test
public void deleteCustomerCaseOrder(){
Session session=sf.openSession();
Transaction tx=session.beginTransaction(); //获取id=1客户
Customer c1=(Customer)session.get(Customer.class, 1); session.delete(c1); tx.commit();
session.close();
} /*
* 知识点14:解除关联关系 ---父子关系
* 解除6号订单和3号客户的关联,同时删除6号订单
*/
@Test
public void deleteOrderOrphan(){
Session session=sf.openSession();
Transaction tx=session.beginTransaction(); //获取id=6订单
Order o6=(Order)session.get(Order.class, 6); //获取id=3客户
Customer c3=(Customer)session.get(Customer.class, 3); //解除关联关系
o6.setCustomer(null);
c3.getOrderes().remove(o6); tx.commit();
session.close();
} }

Customer.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.itcast.many2onedouble.Customer" table="customers">
<id name="id" type="integer">
<column name="id"/>
<generator class="increment"/>
</id>
<property name="name" type="string">
<column name="name"/>
</property> <!-- 配置set集合
set:使用set标签配置客户对应的订单集合
table:订单集合中的订单对应的表,可以不加
cascade="save-update":级联保存和更新:当保存customer对象时,同时要保存customer对象所关联的订单集合orderes集合
"delete":级联删除 inverse="true":表示多的一端(Order端)为主控方法(谁是主控方,谁就说算,多的一端说了算) (全国人民)
一的一端(Customer端)不是主控方法 (国家主席) -->
<set name="orderes" table="orders" cascade="delete-orphan" inverse="true">
<key>
<!-- 对应的是orders表的外键,可以理解为, orderes集合中的订单对象是通过orders表的外键customer_id查询出来的
select * from orders where cutomer_id=客户id 结构是多条记录
-->
<column name="customer_id"/>
</key>
<!--
one-to-many:表示一对多,class表示集合中存放的对象是Order对象
-->
<one-to-many class="cn.itcast.many2onedouble.Order"/>
</set> </class>
</hibernate-mapping>

Order.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.itcast.many2onedouble.Order" table="orders">
<id name="id" type="integer">
<column name="id"/>
<generator class="increment"/>
</id>
<property name="orderNumber" type="string">
<column name="orderNumber"/>
</property>
<property name="price" type="double">
<column name="price"/>
</property> <!--
customer要获取的是Customer对象,
该Customer对象通过orders表的外键customer_id来查询customers表
select * from customes where id=customer_id
many-to-one:使用该标签来映射多对一关联:
name:映射的持久化类中的属性
class:映射的持久化类中的属性的类型 cascade="save-update":级联保存和更新
* 就是将order对象所关联的临时对象Customer变成持久对象(就在session的一级缓存中,就能插入到数据库中)
-->
<many-to-one name="customer" class="cn.itcast.many2onedouble.Customer" cascade="save-update">
<!-- 映射的表中的列 -->
<column name="customer_id"/>
</many-to-one> </class>
</hibernate-mapping>

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property> <!-- 配置数据库的方言,让hibernate知道连接的是哪个数据库-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- 配置利用javaBean和映射文件生成数据库中的表
hibernate.hbm2ddl.auto值
* create:执行时,先查找该表是否存在,如存在先删除表,在创建表
* none:不能创建表,只能往表中插入数据,如表不存在抛出异常,默认值
* update:执行时,
情况一:
先查找该表是否存在,如果表存在,直接插入,如果表不存在,先创建表,再插入数据.
情况二:
先查找该表是否存在,如果表存在,但表的结构不一样,要修改表的结构
-->
<property name="hibernate.hbm2ddl.auto">update</property> <!-- 显示hibernate生成的sql语句 -->
<property name="hibernate.show_sql">true</property> <!-- 显示格式化得sql语句 -->
<property name="hibernate.format_sql">false</property> </session-factory>
</hibernate-configuration>

Hibernate -- 一对多的双向关联关系的更多相关文章

  1. Hibernate 一对多自身双向关联关系 用于类别表的实现

    分类:一对多自身双向关联关系 Java持久化类: package com.hyy.hibernate.one_to_many.domain; import java.util.HashSet; imp ...

  2. Hibernate映射多对多双向关联关系(小案例)

    多对多双向关联关系(Project(工程)/Emp(员工)为案例): 步骤如下: 1.创建Project类,并需要定义集合类型的Emp属性 public class Project { //编号 pr ...

  3. Hibernate一对多(多对一)关联关系

    上一篇博文总结了 Hibernate 的一对一的关联关系, 包括基于主键的单向一对一, 基于外键的单向一对一, 基于外键的双向一对一. 下面咱们说一下 Hibernate 的一对多关联关系. 其实一对 ...

  4. hibernate(十)双向关联关系的CRUD

    本文链接:http://www.orlion.ml/28/ 一.保存 1. 假设一个group有多个user,一个user只属于一个group,当保存user对象到数据库中时可以 User u = n ...

  5. Hibernate -- 映射多对多双向关联关系

    1. 示例代码: Student.java package cn.itcast.many2many; import java.util.HashSet; import java.util.Set; @ ...

  6. 03.Hibernate一对多关联

    前言:在域模型中,类与类之间最普遍的关系就是关联关系,在UML语言中关联关系是有方向的.在数据库中表与表之间也会有关联关系,本节介绍通过Hibernate映射一对多的关联关系,这是一种最普遍的关联关系 ...

  7. Hibernate映射一对多双向关联关系及部门关联属性

    一对多双向关联关系:(Dept/Emp的案例) 既可以根据在查找部门时根据部门去找该部门下的所有员工,又能在检索员工时获取某个员工所属的部门. 步骤如下: 1.构建实体类(部门实体类加set员工集合) ...

  8. Hibernate—— 一对多 和 多对多关联关系映射(xml和注解)总结(转载)

    One to Many 映射关系 多对一单向外键关联(XML/Annotation) 一对多单向外键关联(XML/Annotation) 懒加载和积极加载 一对多双向外键关联(XML/Annotati ...

  9. hibernate 一对多双向关联 详解

    一.解析: 1.  一对多双向关联也就是说,在加载班级时,能够知道这个班级所有的学生. 同时,在加载学生时,也能够知道这个学生所在的班级. 2.我们知道,一对多关联映射和多对一关联映射是一样的,都是在 ...

随机推荐

  1. IOS 计算本周的起至日期

    unsigned units=NSMonthCalendarUnit|NSDayCalendarUnit|NSYearCalendarUnit|NSWeekdayCalendarUnit; NSCal ...

  2. Minecraft Forge编程入门二 “工艺和食谱”

    从现在开始我们就要开始真正写代码了,还没有来得及配置环境的同学可以参考Minecraft Forge编程入门一 "环境搭建"这篇文章来进行环境搭建. 工艺(Craft)和食谱(Re ...

  3. 解决scrapy fetch http://www.csdn.net ModuleNotFoundError No module named 'win32api'和ImportError DLL load failed找不到指定的模块

    1.解决scrapy fetch http://www.csdn.netModuleNotFoundError No module named 'win32api' Python是没有自带访问wind ...

  4. Go语言性能优化

    原文:http://bravenewgeek.com/so-you-wanna-go-fast/ 我曾经和很多聪明的人一起工作.我们很多人都对性能问题很痴迷,我们之前所做的是尝试逼近能够预期的(性能) ...

  5. 【论文翻译】MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications

    MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications 论文链接:https://arxi ...

  6. word2007的配置进度怎么产生的?如何解决?

    那么要怎么解决这个问题呢?既然是安装的,那么我们便道安装控制器文件夹下面去找原因.在WIN8操作系统下,文件夹位于:C:\Program Files (x86)\Common Files\Micros ...

  7. 8.javascript获取表单中两个数字,并判断大小

    获取表单数据的方式: 1.表单注意些id 2.使用document.getElementById("num").value 获取值 3.一定要注意现在得到是string类型,可以用 ...

  8. python list中append()与extend()用法

    列表是以类的形式实现的.“创建”列表实际上是将一个类实例化.因此,列表有多种方法可以操作. 1. 列表可包含任何数据类型的元素,单个列表中的元素无须全为同一类型. 2. append() 方法向列表的 ...

  9. Django的模型层(1)- 单表操作(下)

    一.查询表记录 在学习查询表记录之前,先了解一下QuerySet,这是一种类似列表的数据类型,是由ORM创建的.我们学习查询表记录的方法时,一定要明确哪些方法返回了QuerySet类型,哪些方法返回m ...

  10. fopen() r+、w+属性详解

    r+具有读写属性,从文件头开始写,保留原文件中没有被覆盖的内容: w+具有读写属性,写的时候如果文件存在,会被清空,从头开始写. r 打开只读文件,该文件必须存在. r+ 打开可读写的文件,该文件必须 ...