1.双向 1-n 与 双向 n-1 是完全相同的两种情形,这里使用双向多对一来演示

双向 1-n 需要在 1 的一端可以访问 n 的一端, 反之依然.

出版社和图书的关系:Publishers——Books

2.实体类

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;
//实体类类型属性
private Publishers publisher;
//忽略getter和setter方法
...
}

1端

Publishers.java

public class Publishers {

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

3.映射文件

n端:

<hibernate-mapping package="com.withXml.bothmanyToone.entity" auto-import="false">

    <class name="Books" table="BOTH_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> <!-- 配置多对一关联映射 -->
<many-to-one name="publisher" class="Publishers"
column="PUBLISHER_ID" cascade="save-update"></many-to-one>
</class>
</hibernate-mapping>

1端

<hibernate-mapping package="com.withXml.bothmanyToone.entity" auto-import="false">

    <class name="Publishers" table="BOTH_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> <!--
cascade(级联)级联的意思是指两个对象之间的操作联运关系,对一个对象执行了操作之后,
对其指定的级联对象也需要执行相同的操作,取值:all,none,save_update,delete。
1.all:代码在所有情况下都执行级联操作
2.none:在所有情况下都不执行级联操作
3.save-update:在保存和更新的情况下执行级联操作
4.delete:在删除的时候执行级联操作
inverse:属性设置为true代表一的一方不在拥有关联关系的控制权,而把控制权交给多的一方
-->
<set name="bks" lazy="false" inverse="true" cascade="save-update,delete">
<!-- <key>指定PUBLISHERS数据表的外键,使用的是BOOKS表中的PUBLISHER_ID列 -->
<key column="PUBLISHER_ID"></key>
<one-to-many class="Books"/>
</set>
</class>
</hibernate-mapping>

4.CRUD测试

①保存

/**
* 保存操作,保存1的一端
*/
@Test
public void testBothManyToOneSave(){
//创建出版社对象
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("无"); //双向维护关系
//设置关联关系,指定一到多的关联关系 ,若由1端维护关系,会产生update语句,影响效率,
//所以在1端映射文件中设置inverse="true",控制权交给n端维护关系
publisher.getBks().add(book);
publisher.getBks().add(book2); //设置关联关系,指定多到一的关联关系
book.setPublisher(publisher);
book2.setPublisher(publisher); //执行保存,设置cascade级联属性之后,
//只保存一端即可(哪一端设置级联属性,可以只保存那一段,两端都设置,则任意一端都可以执行保存)
session.save(publisher);
}

②保存2

    /**
* 保存操作
*/
@Test
public void testBothManyToOneSave2(){
//创建出版社对象
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("无"); //双向维护关系
//设置关联关系,指定一到多的关联关系 ,因为会产生update语句,影响效率
//publisher.getBks().add(book);
//publisher.getBks().add(book2); //设置关联关系,指定多到一的关联关系
book.setPublisher(publisher);
book2.setPublisher(publisher); //执行保存,设置cascade级联属性之后,
//只保存一端即可(哪一端设置级联属性,可以只保存那一段,两端都设置,则任意一端都可以执行保存)
session.save(book);
session.save(book2);
}

③查询

/**
* 查询操作
* 查询某出版社出版的图书
*/
@Test
public void testBothManyToOneGet(){
Publishers publisher = (Publishers) session.get(Publishers.class, 1);
Iterator<Books> iterator = publisher.getBks().iterator();
System.out.println(publisher.getName() + "出版的图书有:");
while(iterator.hasNext()){
Books book = iterator.next();
System.out.println(book.getTitle());
}
}

④修改

/**
* 修改操作
* 把id为1的图书所对应的id为1出版社修改为id为2出版社
*/
@Test
public void testBothManyToOneUpdate(){
//获取出版社对象
Publishers publisher = (Publishers) session.get(Publishers.class, 1); //获取图书对象
Books book = (Books) session.get(Books.class, 1);
book.setPublisher(publisher); session.update(book);
}

⑤n端删除

/**
* 删除操作,删除图书信息
*
*/
@Test
public void testBothManyToOneDelete(){
Books book = (Books) session.get(Books.class, 12);
session.delete(book); }

⑥1端删除

/**
* 删除操作,删除出版社信息,以及出版社出版的图书
*
*/
@Test
public void testBothManyToOneDelete2(){
Publishers publisher = (Publishers) session.get(Publishers.class, 1);
session.delete(publisher);
}

五.总结

(双向n对1):其实就是单向n对1和单向1对n同时使用

1端

①实体类:添加集合属性

②映射文件:使用<set> 元素映射集合属性,

name属性指定映射的属性名

inverse属性设置为true代表一的一方不在拥有关联关系的控制权,而把控制权交给多的一方

<key> 元素指定外键,属性值要与n端的<many-to-one> 元素的column属性值一致,

使用<one-to-many class="Books"/> 元素映射关联关系

详细如下:

  <!--
cascade(级联)级联的意思是指两个对象之间的操作联运关系,对一个对象
执行了操作之后,对其指定的级联对象也需要执行相同的操作,
取值:all,none,save_update,delete。
1.all:代码在所有情况下都执行级联操作
2.none:在所有情况下都不执行级联操作
3.save-update:在保存和更新的情况下执行级联操作
4.delete:在删除的时候执行级联操作
inverse:属性设置为true代表一的一方不在拥有关联关系的控制权,
而把控制权交给多的一方
-->
<set name="bks" lazy="false" inverse="true" cascade="save-update,delete">
<!-- <key>指定外键 -->
<key column="PUBLISHER_ID" not-null="true"></key>
<one-to-many class="Books"/>
</set>

n端:

①实体类:添加一个n端实体类型的属性

②映射文件:使用<many-to-one> 元素映射实体类型的属性,column属性指定外键,class指定关联的类的名字。

详细如下:

<!-- 配置多对一关联映射 -->
<many-to-one name="publisher" class="Publishers"
column="PUBLISHER_ID" cascade="save-update">
</many-to-one>

Hibernate(10)_双向n对1(双向1对n)的更多相关文章

  1. Hibernate(12)_基于主键的双向1对1

    一.基于主键的双向1对1 1.介绍: 基于主键的映射策略:指一端的主键生成器使用 foreign 策略,表明根据"对方"的主键来生成自己的主键,自己并不能独立生成主键. <p ...

  2. Hibernate(11)_基于外键的双向1对1

    一.基于外键的双向1对1 对于基于外键的1-1关联,其外键可以存放在任意一边,在需要存放外键一端,增加many-to-one元素.为many-to-one元素增加unique="true&q ...

  3. 转:HIBERNATE一些_方法_@注解_代码示例---写的非常好

    HIBERNATE一些_方法_@注解_代码示例操作数据库7步骤 : 1 创建一个SessionFactory对象 2 创建Session对象 3 开启事务Transaction : hibernate ...

  4. Hibernate(9)_双向n对n

    1.概述 ①双向 n-n 关联需要两端都使用集合属性 ②双向n-n关联必须使用连接表 ③集合属性应增加 key 子元素用以映射外键列, 集合元素里还应增加many-to-many子元素关联实体类 ④在 ...

  5. hibernate 2 一对多、多对一 双向映射

    多对一或一对多中,在多的一方维护关系效率高 一:java实体类 1.Classes.java package cn.gs.ly.school.entity; import java.util.Set; ...

  6. 【Hibernate步步为营】--(一对多映射)之双向关联

    上篇文章讨论了单向关联的一对多映射,在一的一端维护双向的关系这样的做法尽管能实现可是存在非常多缺陷,首先生成非常多多余的SQL语句,由于多的一端不维护关系,仅仅有一的一端维护,在进行操作时一的一端会发 ...

  7. Hibernate双向一对多、双向多对多关联关系中的映射文件怎么写

    这里以一对多关联关系为例.以Country类为一端,Competition类为多端. 一个国家可以有多个赛事,但是一个赛事只能属于一个国家. Country类 public class Country ...

  8. Hibernate 注解(Annotations 二)一对一双向注解

    注解(Annotation),也叫元数据.一种代码级别的说明.它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次.它可以声明在包.类.字段.方法.局部变量.方法参数等的前面,用来 ...

  9. vue 双向绑定(v-model 双向绑定、.sync 双向绑定、.sync 传对象)

    1. v-model实现自定义组件双向绑定 v-model其实是个语法糖,如果没按照相应的规范定义组件,直接写v-model是不会生效的.再说一遍,类似于v-on:click可以简写成@click,v ...

随机推荐

  1. UIActionSheet的常用方法

    enum UIActionSheetStyle : Int { case Automatic // take appearance from toolbar style otherwise uses ...

  2. python基础——dict和set(字典和集合)

    1.dict:pop(),get(),in,{} >>> dicttest = {'marry':34,'jucy':56} --初始化>>> dicttest{' ...

  3. Telnet和SSH

    1. 协议用途 Telnet和SSH用于远程访问服务器的的两大常用协议.利用它们,我们可以管理并监控生产服务器和企业服务器,更新服务器内核,安装最新的软件包和补丁,能够远程登录服务器,开展软件开发.测 ...

  4. 【转】Android 模拟器横屏竖屏切换设置

    http://blog.csdn.net/zanfeng/article/details/18355305# Android 模拟器横屏竖屏切换设置时间:2012-07-04   来源:设计与开发   ...

  5. crunch创建自己的密码字典文件

    http://www.2cto.com/article/201608/542026.html

  6. Docker镜像、容器剖析

    我们通常所说的docker是什么? 在这里英文本意为“搬运工”这里指的的docker搬运点的是集装箱,集装箱装的是够任意类型的APP,开发者通过Docker可以将app变成一种标准化,可移植的.自管理 ...

  7. net core体系-Xamarin-1概要

    大家在开发领域都知道Java是跨平台的,但是很多人认为.NET是只能在Windows下运行,不具有跨平台的特性,这种说法其实是不妥的. .NET其实在设计之初也是考虑像Java一样跨平台的,我们知道. ...

  8. ELK 环境搭建3-Logstash

    一.Logstash是一款轻量级的日志搜集处理框架,可以方便的把分散的.多样化的日志搜集起来,并进行自定义的处理,然后传输到指定的位置,比如某个服务器或者文件或者中间件. 二.搭建 1.因为要涉及到收 ...

  9. echarts Y轴的刻度 跟数据对应---tooltip-formatter

    var xAxisData = ['2018-01', '2018-02', '2018-03', '2018-04', '2018-05', '2018-06', '2018-07', '2018- ...

  10. L3-001 凑零钱 (30 分) dfs加后缀剪枝

    韩梅梅喜欢满宇宙到处逛街.现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债.韩梅梅手边有 1 枚来自各个星球的硬币,需要请你帮她盘算一下,是 ...