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. java运算符-算数、赋值、比较

    1.算术运算符 运算符是用来计算数据的符号.数据可以是常量,也可以是变量.被运算符操作的数我们称为操作数. 运算符 运算规则 范例 结果 + 正号 +3 3 + 加 2+3 5 + 连接字符串 “中” ...

  2. 【Ruby】Mac gem的一些坑

    前言 自上一次升级MacOS系统后出现jekyll无法构建的问题,当时处理半天.谁知道最近又升级了MacOS,荒废博客多时,今天吝啬写了一篇准备发布,构建报错,问题重新.还是记录下,以防下次升级出问题 ...

  3. JMeter执行压测输出HTML图形化报表(二)

    命令行模式将jtl转成测试图表 注意此方法只使用jmeter3.0以后版本 第一种:在测试过程中将jtl转成测试报告(在jmeter的bin目录下执行) jmeter -n -t baidu_requ ...

  4. 去掉select的原有样式

    1:设置select的边框为0px,背景设成透明(background: transparent;),这时候你会看到边框没有了,但是小三角还是在的.再在select外面加个div,固定死div的宽度, ...

  5. windows快速进入安装目录

    ctrl+R 输入%LOCALAPPDATA%\+应用名字 %LOCALAPPDATA%\composer

  6. 043 关于 loadrunner 返回 http 500 错误解决思路

    这个支持项目中,总是出现500的问题,后来发现是redis总是崩掉. 后来,在压力测试,500的问题,又开始不断出现,虽然不是我自己处理的,但是没少吃苦头. 看了这篇文章,感觉说的还是很有道理,如何来 ...

  7. day5 列表的增删改查

    1,列表的增删改查,其他操作.2,元祖.3,列表的嵌套操作.4,开一点dict. 昨日内容回顾: 字符串的方法:1,find通过元素找索引,可切片,找不到返回-12,index,找不到报错.3,spl ...

  8. eclipse里面svn比较之前版本的代码

    team——显示资源历史记录比较

  9. c++容器加迭代器和python装饰器的对比

    c++利用对象实现简单数据的测试: class TestDataEmptyArray { public: static vector<int> get_array() { std::vec ...

  10. linux 学习笔记 显示压缩文件 gong.zip 的文件内容

    #zip -v gong zip zip info: xxx >删除压缩文件中俄smart.txt 文件 #zip -d gong.zip smart.txt deleting:smart.tx ...