1.单向一对多(@OneToMany)关联是比较少用的(一般用双向一对多代替)。

2.实体类:

1端:Publishers.java

public class Publishers {

    private Integer id;
private String Name;
//集合属性
private Set bks = new HashSet<>();
//忽略getter和setter方法
...
}

n端:Books.java

public class Books {

    private Integer Id;
private String Title;
private String Author;
private String ISBN;
private int WordCount;
private double UnitPrice;
private String ContentDescription;
//忽略getter和setter方法
...
}

3.映射文件

1端:Publishers.hbm.xml

<hibernate-mapping>

    <class name="com.withXml.oneTomany.entity.Publishers" table="PUBLISHERS">

        <id name="id" type="java.lang.Integer" access="field">
<column name="ID" />
<generator class="native" />
</id> <property name="Name" type="java.lang.String">
<column name="NAME" />
</property>
<!-- 配置单向一对多配置,在一的一方进行配置 -->
<!--set节点:
cascade(级联)级联的意思是指两个对象之间的操作联运关系,对一个对象执行了操作之后,
对其指定的级联对象也需要执行相同的操作,取值:all,none,save_update,delete。
1.all:代码在所有情况下都执行级联操作
2.none:在所有情况下都不执行级联操作
3.save-update:在保存和更新的情况下执行级联操作
4.delete:在删除的时候执行级联操作
name:保存多端对象集合的属性。
table:多端的数据表。
<key>:指定多端的外键。
-->
<set name="bks" lazy="false" table="BOOKS" cascade="save-update,delete">
<key column="PUBLISHER_ID"></key>
<one-to-many class="com.withXml.oneTomany.entity.Books"/>
</set>
</class>
</hibernate-mapping>

n端:Books.hbm.xml

<hibernate-mapping package="com.withXml.oneTomany.entity">

    <class name="Books" table="BOOKS">

        <id name="Id" type="java.lang.Integer" access="field">
<column name="ID" />
<generator class="native" />
</id> <property name="Title" type="java.lang.String">
<column name="TITLE" />
</property> <property name="Author" type="java.lang.String">
<column name="AUTHOR" />
</property> <property name="ISBN" type="java.lang.String">
<column name="ISBN" />
</property> <property name="WordCount" type="integer">
<column name="WORD_COUNT"/>
</property> <!-- 映射数据表字段你的类型,可以在property 里面使用type设置,也可以在column里面使用 sql-type设置-->
<property name="UnitPrice">
<column name="UNIT_PRICE" sql-type="double" />
</property> <property name="ContentDescription" type="java.lang.String">
<column name="CONTENT_DESCRIPTION" />
</property> </class>
</hibernate-mapping>

5.CRUD测试

①保存

/**
* 添加操作
* 添加图书和出版社信息
*/
@Test
public void testOneToManySave(){
//新建出版社对象
Publishers publisher = new Publishers();
publisher.setName("北京大学出版社");
//新建图书对象
Books book = new Books();
book.setTitle("大学英语");
book.setISBN("2018012103");
book.setAuthor("李玲");
book.setWordCount(10000);
book.setUnitPrice(95.5);
book.setContentDescription("无"); //新建图书对象
Books book2 = new Books();
book2.setTitle("管理学");
book2.setISBN("2018012104");
book2.setAuthor("张青");
book2.setWordCount(10000);
book2.setUnitPrice(95.5);
book2.setContentDescription("无"); //设定关联关系,从多的一端维护关系,想要从多端维护关联关系需要在多端配置many-to-one,三条insert语句,推荐使用这种方式
//book.setPublisher(publisher);
//book2.setPublisher(publisher); //设定关联关系,从一的一端维护关系,想要从一端维护关联关系需要在一端配置one-to-many,三条insert语句,两条update语句,不推荐使用这种方式,因为这里需要演示1对n关联关系,所以使用该方法
publisher.getBks().add(book);
publisher.getBks().add(book2); //执行保存操作,先保存1的一端,在保存n的一端
session.save(publisher);
session.save(book);
session.save(book2); }

②获取

/**
* 获取操作
* 通过出版社获取图书信息
*/
@Test
public void testOneToManyGet(){
//根据id获取出版社对象
Publishers publisher = (Publishers) session.get(Publishers.class, 1);
System.out.println(publisher.getName() + "出版的图书有:");
//获取集合的迭代器
Iterator iterators = publisher.getBks().iterator();
while(iterators.hasNext()){
Books book = (Books) iterators.next();
System.out.println(book.getTitle());
} }

③修改

/**
* 修改操作
* 功能:修改id为1的出版社的名字
*/
@Test
public void testOneToManyUpdate(){
Publishers publisher = (Publishers) session.get(Publishers.class, 2);
publisher.setName("同济大学出版社");
session.update(publisher);
}

④删除

/**
* 删除操作,在多对一映射中,无法从1的一端删除,在一对多映射中,可以中1的一端删除记录,
*同时还会强制把n端的外键也删除
*功能:删除出版社,同时引用该记录的外键也删除。
*/
@Test
public void testOneToManyDelete(){
//从n端删除
Books book = (Books) session.get(Books.class, 1);
session.delete(book); //从1端删除,同时n端引用的外键也会被删除
// Publishers publisher = (Publishers) session.get(Publishers.class, 1);
// session.delete(publisher);
}

级联操作需要在1端的映射文件中set节点下,设置级联属性:

cascade(级联)级联的意思是指两个对象之间的操作联运关系,对一个对象执行了操作之后,

对其指定的级联对象也需要执行相同的操作,取值:all,none,save_update,delete。

1.all:代码在所有情况下都执行级联操作

2.none:在所有情况下都不执行级联操作

3.save-update:在保存和更新的情况下执行级联操作

4.delete:在删除的时候执行级联操作

⑤级联添加

/**
* 级联添加
* 需求:添加出版社时,把出版社出版的图书添加到数据表中
*/
@Test
public void testOneToManyCascadeSave(){
//新建出版社对象
Publishers publisher = new Publishers();
publisher.setName("北京大学出版社");
//新建图书对象
Books book = new Books();
book.setTitle("大学英语");
book.setISBN("2018012103");
book.setAuthor("李玲");
book.setWordCount(10000);
book.setUnitPrice(95.5);
book.setContentDescription("无"); //新建图书对象
Books book2 = new Books();
book2.setTitle("管理学");
book2.setISBN("2018012104");
book2.setAuthor("张青");
book2.setWordCount(10000);
book2.setUnitPrice(95.5);
book2.setContentDescription("无"); //设定关联关系,从多的一端维护关系,想要从多端维护关联关系需要在多端配置many-to-one,三条insert语句,推荐使用这种方式
//book.setPublisher(publisher);
//book2.setPublisher(publisher); //设定关联关系,从一的一端维护关系,想要从一端维护关联关系需要在一端配置one-to-many,三条insert语句,两条update语句,不推荐使用这种方式,因为演示1对n,所以使用该方法
publisher.getBks().add(book);
publisher.getBks().add(book2); //设置cascade级联属性之后,可只保存1的一端即可。可省略多的一端的保存操作,反之则不行因为没有多对一映射
session.save(publisher);
//session.save(book);
//session.save(book2); }

⑥级联更新

    /**
* 级联更新
*需求:把id为3的书的出版社改为出版社id为1的出版社
*/ @Test
public void testOneToManyCascadeUpdate(){
//获取id为1的图书对象
Books book = (Books) session.get(Books.class, 3);
//获取id为1的出版社对象
Publishers publisher = (Publishers) session.get(Publishers.class, 1); publisher.getBks().add(book);
//保存出版社对象,三个select,一个update
//session.save(publisher); //保存图书对象,三个select,一个update
session.save(book);
}

⑦级联删除

    /**
* 级联删除
* 需求:删除出版社时,删除该出版社所出版社的图书
*/
@Test
public void testOneToManyCascadeDelete(){
Publishers publisher = (Publishers) session.get(Publishers.class, 4);
//两个select、一个update、三个delete
session.delete(publisher);
}

一对多关联关系

总结:

1端:

①实体类中添加一个集合属性

②映射文件中使用set元素映射数据库字段,并在set节点中配置<one-to-many> 子节点以映射关联关系

③保存操作时,有没有发送多余的update语句在于哪端维护关联关系,而哪端维护关联关系在于是<one-to-many> 还是 <many-to-one>

即推荐使用由n端维护关联关系,使用<many-to-one> 来映射关系,在保存时使用n端实体类中的setter方法

//n端保存1端,订单中设置客户信息
order.setCustomer(customer);
order2.setCustomer(customer);

④级联操作少用

n端:

实体类:普通的JavaBean

映射文件:类属性和数据库字段一一映射即可

Hibernate(7)关联关系_单向1对n的更多相关文章

  1. Hibernate(6)关联关系_单向n对1

    1.单向 n-1 关联只需从 n 的一端可以访问 1 的一端 2.实体类 n端:Order.java public class Order { private Integer orderId; pri ...

  2. 009一对一 主键关联映射_单向(one-to-one)

    009一对一  主键关联映射_单向(one-to-one) ²  两个对象之间是一对一的关系,如Person-IdCard(人—身份证号) ²  有两种策略可以实现一对一的关联映射 主键关联:即让两个 ...

  3. Hibernate —— 映射关联关系

    一.映射多对一关联关系. 1.单向的多对一 (1)以 Customer 和 Order 为例:一个用户可以发出多个订单,而一个订单只能属于一个客户.从 Order 到 Customer 是多对一关联关 ...

  4. Hibernate的关联映射——单向1-N关联

    Hibernate的关联映射--单向1-N关联 单向1-N关联的持久化类里需要使用集合属性.因为1的一端需要访问N的一端,而N的一端将以集合(Set)形式表现.从这个意义上来看,1-N(实际上还包括N ...

  5. Hibernate的关联映射——单向1-1关联

    Hibernate的关联映射--单向1-1关联 对于单向的1-1关联关系,需要在持久化类里增加代表关联实体的成员变量,并为该成员变量添加setter方法和getter方法.从持久化类的代码上看,单向1 ...

  6. Hibernate的关联映射——单向N-1关联

    Hibernate的关联映射--单向N-1关联 N-1是非常常见的关联关系,最常见的父子关系也是N-1关联,单向的N-1关联只需从N的一端可以访问1的一端. 为了让两个持久化类能够支持这种关联映射,程 ...

  7. JPA(六):映射关联关系------映射单向一对多的关联关系

    映射单向一对多的关联关系 新建项目项目请参考<JPA(二):HellWord工程>,基于上一章讲解的<JPA(五):映射关联关系------映射单向多对一的关联关系>中的例子进 ...

  8. hibernate一对一外键单向关联

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

  9. hibernate一对一主键单向关联

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

随机推荐

  1. jquery中关于对象类型的判断原理

    class2type[ core_toString.call(obj) ] jquery中关于对象类型的判断原理 jquery源码中关于类型判断的工具函数为type,调用方法为$.type()或者jQ ...

  2. T37302 P哥的桶

    题解: 比较简单的一道题 线段树+线性基 显然离线处理出位置 然后线段树updata的时候暴力合并线性基 nlogn^3 一个常数优化就是线性基已满就直接返回这个线性基 还有个优化是用快速找到第一个1 ...

  3. mySql中SUBSTRING_INDEX函数用法

    SUBSTRING_INDEX(str,delim,count) 返回字符串 str 中在第 count 个出现的分隔符 delim 之前的子串.如果 count 是一个正数,返回从最后的(从左边开始 ...

  4. JMeter实现Oracle参数化(1)

    http://www.ithao123.cn/content-10469577.html

  5. python--闭包、装饰器

    1.闭包 ①.python中一切皆对象,函数中嵌套函数肯定也是合理的,这种函数也叫作内嵌函数(内部函数) ②.内嵌函数只能被外部函数调用,被外部函数以外的区域被调用,就会出错!!! ③.若内部函数中引 ...

  6. List接口相对于Collection接口的特有方法

    [添加功能] 1 void add(int index,Object element); // 在指定位置添加一个元素. [获取功能] 1 Object get(int index); // 获取指定 ...

  7. miniui表格load数据成功后,回调函数,其中setData要用如下方法

    init: function () { mini.parse(); this.grid = mini.get("jsDatagrid"); var grid1 = mini.get ...

  8. Webmin详细安装过程及问题解决

    管理系统是件艰巨的任务,创建用户账户,配置服务,检查日志,还有系统管理员必须面对的所有其他的职责,都使系统管理工作成为一个不小的负担.下面介绍一个叫webmin的软件,webmin软件安装后能让读者从 ...

  9. js小函数工具

    突然想到建一片文章关于自己所学到的一些小函数,今后需要的时候可以直接当工具使用. 1.获取当前时间小程序. function showTime(){ var show_day=new Array('星 ...

  10. Vue渲染列表,在更新data属性后,列表未更新问题

    初始化代码如下var tableModel = new Vue({el: '#datatable',data: {items: listData}}); 当我对列表操作时,listData=>n ...