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. 第k个互质数(二分 + 容斥)

    描述两个数的a,b的gcd为1,即a,b互质,现在给你一个数m,你知道与它互质的第k个数是多少吗?与m互质的数按照升序排列. 输入 输入m ,k (1<=m<=1000000;1<= ...

  2. mysql表管理

    4.1 查看所有表 查看所有表语句: show tables; 例: mysql> show tables; +-----------------+ | Tables_in_emp | +--- ...

  3. keepalived高可用配置注意事项

    安装注意事项: 1.关闭防火墙或者打开防火墙vrrp协议的通过,centos6 和centos7打开方式不同 2.一定要关闭防火墙 3.配置完成后重启网卡和keepalived服务 4.日志:/var ...

  4. npm淘宝镜像的设置和删除

    设置 npm config set registry https://registry.npm.taobao.org npm config set disturl https://npm.taobao ...

  5. lr场景异常Continuing after Error -26479: Conversion of form submission data to the target charset failed: U_TRUNCATED_CHAR_FOUND解决方法

    在lr压测场景中执行,发现 一个事务都没有成功,很是奇怪,发现用linux的agent各种问题 查看lr运行日志 看到这里基本确定是编码的问题,然后想起lr设置编码的地方就那么几个,所以逐个尝试 改完 ...

  6. net core体系-API-1Ocelot-(1)概要

    从这篇开始探讨Ocelot,Ocelot是一个.NET API网关,仅适用于.NET Core,用于.NET面向微服务/服务的架构中.当客户端(web站点.ios. app 等)访问web api时, ...

  7. python josn包

    Python josn包中的编码与解码方法 对于Python数据类型进行编码解码 json.dumps  对python的数据类型进行json格式编码 :(将dict转为json格式) eg: imp ...

  8. POJ 1222 EXTENDED LIGHTS OUT (熄灯问题)

    Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8417   Accepted: 5441 Description In an ...

  9. 如何将.SQL文件的数据导入到Mysql的数据库中

    一.用cmd的调试环境导入.sql文件中的数据: WinR键打开cmd输入: MySQL -u root -p 进入MySQL后MySQL>use DR;   MySQL> source  ...

  10. SSH框架学习------struts2前后台传值(二)

    struts2的Action类一般都会继承(extends)ActionSupport类(Action类,即实现action的类)1.前传后:jsp里<input type="text ...