码农小汪-Hibernate学习8-hibernate关联关系注解表示@OneToMany mappedBy @ManyToMany @JoinTable...

近期我也是有点郁闷,究竟是程序中处理关联关系。还是直接使用外键处理关联关系呢?这个的说法不一致!程序中处理这样的关联关系的话。自己去维护这样的约束。这样的非常乐观的一种做法!或者是直接在数据库中处理这样的直接的外键关联,悲观的做法!刚刚看到个帖子。有的公司表中一个外键都没得。直接在程序中处理这样的关联关系。假设在Hibernate中处理外键关系的话。我们首先得有个主表的对象吧,然后在创建外键。感觉有点啰嗦。为啥不直接操作呢!

我仅仅要晓得你这个Id是外键即可了。各有各的说法。我想你也在思考这个问题。

现实的世界中确实非常少有孤立纯在的东西。大多都是两者之间纯在某种关系的。有单向关系 仅仅能通过老师訪问学生。或者学生訪问老师
或者双向关系 两个都能够相互的訪问

单向关系
1-1
1-N
N-1
N-N
双向关系
1-1
1-N
N-N

单向N_1关联是最多的,多个人住同一个地址。我们仅仅须要从人这一端知道他的住址即可了,不是必需知道某个地址的用户。

为了让我们两个持久化实体关联。程序在N的一端添加持久化实体的一个属性,该属性指向引用1的那一端的关联实体
对于N-1(不管是单向关联还是双向关联),都仅仅须要在N的一端使用@ManyToONe修饰关联实体的属性
有以下的一些属性,事实上之前我也说过的,非常easy忘记。没事的时候自己看看

属性说明
Cascade级联操作策略CascadeType.ALL….
Fetch抓取关联实体的策略,之前说过FechType.Lazy 延迟和马上
targetEntity该属性的关联实体的类名,在默认情况下通过反射获得类名

默认情况下我们的targetEntity无需指定这个属性的。但在一些特殊的情况下,比如使用@OneToMany.@ManyToMany 修饰 1-N N-N关联的时候。关联实体集合不带泛型信息就必须指定了

无连接的N-1

无连接也就是不须要第三张表,维护我们的关联关系。对于N_1关联关系,我们仅仅须要在N的一端添加一列外键即可。

让外键的值记录到该属性的实体即可。

Hibernate使用@JoinColumn来修饰代表关联实体的属性,用于映射底层的外键列。

这样的就不使用连接表了

好啦,我们看一下样例

多个人相应同一个地址

@Entity
@Table(name="person_inf")
public class Person
{@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定义该Person实体关联的Address实体@ManyToOne(targetEntity=Address.class)// 映射外键列,指定外键列的列名为address_id、不同意为空@JoinColumn(name="address_id" , nullable=false)@Cascade(CascadeType.ALL)private Address address;........
}Address 里面非常正常就一个Id。和地址具体

他们建立的表什么样子呢?
person_inf
person_id age name address_id
address_inf
address_id addressDetail

怎样操作对象呢,由于address_id 是一个外键。

假设我们保存一个Person对象在我们的表中的话。我们应该首先有一个Address 对象吧。

能够是存在数据库中的。也能够才瞬态对象。我们在插入的时候级联操作。会先插入address_inf这个表中,然后才干够使用外接啦。不然会报错的,由于没有存在的外键,肯定不行啦~

Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();// 创建一个Person对象Person p = new Person();// 创建一个瞬态的Address对象Address a = new Address("广州天河");          p.setName("Test");p.setAge(21);// 设置Person和Address之间的关联关系p.setAddress(a);// 持久化Person对象session.persist(p);//级联的插入操作哦~。地址一定先于person插入数据表中,这里必须设置级联操作,不然要报错// 创建一个瞬态的Address对象Address a2 = new Address("上海虹口");        // 改动持久化状态的Person对象p.setAddress(a2);                            tx.commit();HibernateUtil.closeSession();

有连接的N-1

我们的关联关系的维护让第三张表来维护啦。

对于大部分的N_1单向关系,仅仅要基于外键的关联关系维护已经够了。
假设有须要使用连接表来维护关联关系,程序能够使用连接表显示的维护这样的关系,所谓连接表就是建立第三张表格来维护我们的关系即可了。使用@JoinTable

以下的是java给的样例,除了这些属性外,我们还能够指定targetEntity。指定关联的实体是哪个!

也就是生成表的是哪个表所相应的实体。

 @JoinTable(name="CUST_PHONE",//相对于当前实体的外键,的列名。

參照的列名,也就是数据表中的名字 joinColumns= @JoinColumn(name="CUST_ID", referencedColumnName="ID"), //这个也是个外键,仅仅是不说当前实体里面的属性。 inverseJoinColumns= @JoinColumn(name="PHONE_ID", referencedColumnName="ID") )

我们来看个样例就知道啦

@Entity
@Table(name="person_inf")
public class Person
{// 标识属性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定义该Person实体关联的Address实体@ManyToOne(targetEntity=Address.class)// 显式使用@JoinTable映射连接表@JoinTable(name="person_address", // 指定连接表的表名为person_address// 指定连接表中person_id外键列,參照到当前实体相应表的主键列joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id", unique=true),// 指定连接表中address_id外键列,參照到当前实体的关联实体相应表的主键列inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id"))private Address address;
.....
@Entity
@Table(name="address_inf")
public class Address
{// 标识属性@Id @Column(name="address_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private int addressId;// 定义地址具体信息的成员变量private String addressDetail;
}

这里产生的表的话,曾经的person的表不会改变address也不会变
仅仅是添加一个外表
person_address ——table
address_id person_id
使用连接表维护关系

单向1-1关联

看上去 1-1 和N-1 几乎相同啊,都须要在持久化实体中添加代表关联实体的成员变量,从代码上看没得什么差别。由于N的一端和1的一端都能够直接的訪问关联的实体,。
不管单向的还是双向的1-1关联,都须要使用@OneToOne修饰关联实体的属性
有以下的
级联操作,抓取属性。optional 关联关系是否可选。目标关联实体的类名targetEntity.还有个重要的
mappedBy:该属性合法的属性值为关联实体的属性名该属性指定关联实体中的哪个属性可引用当前的实体

样例:基于外键的单向 1-1 关联,无连接表

@Entity
@Table(name="person_inf")
public class Person
{// 标识属性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定义该Person实体关联的Address实体@OneToOne(targetEntity=Address.class)// 映射名为address_id的外键列,參照关联实体相应表的addres_id主键列@JoinColumn(name="address_id", referencedColumnName="address_id" , unique=true)private Address address;地址肯定是独一无二的嘛,对不正确!添加unique约束~.....
}

有连接表的也是几乎相同,理解啦买即可了

@Entity
@Table(name="person_inf")
public class Person
{// 标识属性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定义该Person实体关联的Address实体@OneToOne(targetEntity=Address.class)@JoinTable(name="person_address",joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id" , unique=true),inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id", unique=true))private Address address;......
}

上面的东西,我相信仅仅要第一个看懂了即可了,跟着画样子涩。1-1嘛。肯定不能一样的涩。

单向的1-N

1的一端要訪问N的一端。肯定的加个集合涩和前面的集合非常类似,可是如今的集合里的元素是关联的实体啦。对于单向的1—N关联关系。

仅仅须要在1的一端加入set类型的成员变量,记录全部的关联的实体。

即可了。具体怎么操作,我们慢慢的说来。

一个个字的打还是能够的。添加自己的理解
@OneToMany
级联。抓取,目标实体,mappedBy

无连接表的单向1-N

1个人有多个住处~~~贪官!

不然怎么买的起这么多房子,如今的房价你又不是不知道。哼~

@Entity
@Table(name="person_inf")
public class Person
{@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定义该Person实体全部关联的Address实体,没有指定cascade属性@OneToMany(targetEntity=Address.class)// 映射外键列。此处映射的外键列将会加入到关联实体相应的数据表中。为啥呢?@JoinColumn(name="person_id" , referencedColumnName="person_id")private Set<Address> addresses= new HashSet<>();........}

这里的外键列不会添加到当前实体相应的数据表中,而是添加到,关联实体Address相应的数据表中,有点特殊!

为什么。之前我们使用set集合的时候都必须在添加一个表记得?仅仅只是这里添加到了关联实体里面去了。

而不是在添加一张表~~

N的端不维护关系,没得变化~

有连接的1-N

@Entity
@Table(name="person_inf")
public class Person
{// 标识属性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定义该Person实体全部关联的Address实体@OneToMany(targetEntity=Address.class)// 映射连接表为person_address@JoinTable(name="person_address",// 定义连接表中名为person_id的外键列。该外键列參照当前实体相应表的主键列joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id"),// 定义连接表中名为address_id的外键列。// 该外键列參照当前实体的关联实体相应表的主键列inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id", unique=true))private Set<Address> addresses= new HashSet<>();
...
}

这里是1对N 1个人有多个住的地方,可是每一个都是不一样的,所以要添加unique约束
由于採用连接表了,我们的Person表中没有存在维护连接关系,能够随意的持久化操作。


1个person 2个adress 要插入5次操作哦
自己想想为什么?

单向的N-N也是须要的

@ManyToMany
N-N关系必须须要连接表啦,和有连接的1-N类似,可是要把unique约束去掉啦~
直接改动啦,上面那个~

@Entity
@Table(name="person_inf")
public class Person
{// 标识属性@Id @Column(name="person_id")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer id;private String name;private int age;// 定义该Person实体全部关联的Address实体@ManyToMany(targetEntity=Address.class)// 映射连接表为person_address@JoinTable(name="person_address",// 定义连接表中名为person_id的外键列,该外键列參照当前实体相应表的主键列joinColumns=@JoinColumn(name="person_id", referencedColumnName="person_id"),// 定义连接表中名为address_id的外键列,// 该外键列參照当前实体的关联实体相应表的主键列inverseJoinColumns=@JoinColumn(name="address_id", referencedColumnName="address_id"))private Set<Address> addresses= new HashSet<>();
...
}

转载于:https://www.cnblogs.com/wzzkaifa/p/7354159.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/282745.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML中弹窗中加入图片,javascript里怎么实现点击图片弹出对话框?

JavaScript中可以使用document.getElementsByTagName方法后去img标签&#xff0c;然后遍历所有img标签并为其添加点击事件实现点击弹出对话框。JavaScript实现点击图片弹出对话框&#xff1a;img {width: 500px;height: 300px;}//获取所有的img标签var imgObjs document.getEl…

Java学习优秀网站

各类程序员学习路线图&#xff1a; http://www.runoob.com/coder-learn-path 博学谷&#xff1a; http://v.itcast.cn/map/22.html 慕课网&#xff1a; http://www.imooc.com/course/programdetail/pid/31 转载于:https://www.cnblogs.com/Arsene/p/6441831.html

Dcloud课程2 什么是Dcloud

Dcloud课程2 什么是Dcloud 一、总结 一句话总结&#xff1a;DCloud提供了一套快速开发应用的跨平台技术方案。 1、DCloud的产品架构&#xff1f; MUI(H5)HBuilder 2、什么是MUI&#xff1f; 最接近原生体验的移动App的UI框架。 3、什么是H5&#xff1f; html5功能增强标准 二、…

html5 轮询自动刷新数据,后台调用exe,前端定时轮询调用结果

前提使用asp.net core 2.1前端使用vueui使用element-ui前端发送请求用Axios新建asp.net core程序1.jpg修改Index.html{Layout null;}test{{ msg }}发送请求打开记事本// 创建 Vue 实例&#xff0c;得到 ViewModelvar vm new Vue({el: #app,data: {msg: 准备发送请求打开exe},…

洛谷 P2951 [USACO09OPEN]捉迷藏Hide and Seek

题目描述 Bessie is playing hide and seek (a game in which a number of players hide and a single player (the seeker) attempts to find them after which various penalties and rewards are assessed; much fun usually ensues). She is trying to figure out in which…

使用ssh免密码登录Linux服务器

频繁登录Linux服务器时&#xff0c;使用ssh <username><host>的方式登录&#xff0c;但是每次都需要输入密码是件很麻烦的事。我们还可以使用私钥/公钥对的方式在免密码登录服务器。首先需要在远程服务器中安装ssh-server服务&#xff0c;才可以使用ssh登录。如果没…

linux下tomcat开启远程调试

1.center下&#xff0c;在startup.sh文件首行中添加如下语句 declare -x CATALINA_OPTS"-server -Xdebug -Xnoagent -Djava.compilerNONE -Xrunjdwp:transportdt_socket,servery,suspendn,address8000"(不要换行&#xff0c;要在同一行)Ubuntu下&#xff0c;在catali…

.NET 7 RC1 发布

原文链接&#xff1a;https://devblogs.microsoft.com/dotnet/announcing-dotnet-7-rc-1/[1]原文作者&#xff1a;Jeremy Likness&#xff0c;Angelos Petropoulos&#xff0c;Jon Douglas翻译&#xff1a;沙漠尽头的狼(谷歌翻译加持)今天我们宣布 .NET 7 候选版本 1。这是生产…

html 字符串最后加空格,html space空格符

htmlcss 代码在网页中如何插入打出空格字符实现方法**摘要浏览器总是会截短 HTML 页面中的空格。HTML将所有空格字符&#xff0c;制表符&#xff0c;空格和回车符压缩为一个字符。如果要缩进段落&#xff0c;则不能简单地键入五个空格然后开始文本。 如果您在文本中写 10 个空格…

.NET MAUI实战 FilePicker

1.概要最近在迁移 GeneralUpdate.Tool的时候需要用到文件选择&#xff0c;在MAUI中可以使用FilePicker进行选择。ref1: https://gitee.com/Juster-zhu/GeneralUpdateref2:https://docs.microsoft.com/zh-cn/dotnet/maui/platform-integration/storage/file-picker?tabswindows…

SQL Server中,with as使用介绍

一&#xff0e;WITH AS的含义 WITH AS短语&#xff0c;也叫做子查询部分&#xff08;subquery factoring&#xff09;&#xff0c;可以让你做很多事情&#xff0c;定义一个SQL片断&#xff0c;该SQL片断会被整个SQL语句所用到。有的时候&#xff0c;是为了让SQL语句的可读…

从新手机到老股票 闲鱼为何会沦为骗子与营销的新平台?

国内电商一直空缺一个有规模的综合二手交易平台。闲鱼的出现&#xff0c;有一定程度上满足了喜欢淘二手、喜欢“捡漏”的用户需求。虽加入了担保和第三方支付等环节&#xff0c;但这种随机的二手交易行为不可避免地会出现上当、受骗的情况出现。本质上来说&#xff0c;闲鱼仍然…

网上书店模板asp与html,一个简单的网上书城的例子(三)_asp实例

buy.asp:显示商品和用户购物&#xff01;DbPath SERVER.MapPath("ShopBag.mdb")Set conn Server.CreateObject("ADODB.Connection")conn.open "driver{Microsoft Access Driver (*.mdb)};dbq" & DbPathCategoryIDRequest("CategoryID…

使用C#编写一个.NET分析器(一)

译者注这是在Datadog公司任职的Kevin Gosse大佬使用C#编写.NET分析器的系列文章之一&#xff0c;在国内只有很少很少的人了解和研究.NET分析器&#xff0c;它常被用于APM&#xff08;应用性能诊断&#xff09;、IDE、诊断工具中&#xff0c;比如Datadog的APM&#xff0c;Visual…

内置数据类型

Java语言提供了八种基本类型。六种数字类型&#xff08;四个整数型&#xff0c;两个浮点型&#xff09;&#xff0c;一种字符类型&#xff0c;还有一种布尔型。 byte&#xff1a; byte 数据类型是8位、有符号的&#xff0c;以二进制补码表示的整数&#xff1b; 最小值是 -128&…

算法学习之循环结构程序设计

for循环 打印1,2,3&#xff0c;...&#xff0c;n每个占一行。 #include <conio.h> #include<stdio.h> int main(){int i,n;scanf("%d",&n);for(i1;i<n;i){printf("%d\n",i);}getch();return 0; } 分支结合循环&#xff0c;威力很强大 输…

Linux常用命令 (分门别类)

一、系统安全: su: 用于切换当前用户身份到其他用户身份&#xff0c;变更时须输入所要变更的用户帐号与密码 sudo: 用来以其他身份来执行命令&#xff0c;预设的身份为root lastlog: 用于显示系统中所有用户最近一次登录信息 lastb: 用于显示用户错误的登录列表&#x…

hibernate自定义校验器使用(字段在in范围之内)

2019独角兽企业重金招聘Python工程师标准>>> 1.自定义注解类DigitsMustIn Constraint(validatedBy DigitsMustInValidator.class) //具体的实现 Target({java.lang.annotation.ElementType.METHOD,java.lang.annotation.ElementType.FIELD}) Retention(java.lang.a…

sql将html转成excel,使用SQL*PLUS,构建完美excel或html输出

通过SQL*PLUS我们可以构建友好的输出&#xff0c;满足多样化用户需求。本例通过简单示例&#xff0c;介绍通过sql*plus输出xls&#xff0c;html两种格式文件.首先创建两个脚本:1.main.sql用以设置环境&#xff0c;调用具体功能脚本2.功能脚本-get_tables.sql为实现具体功能之脚…

[cogs347]地震

COGS&#xff1a;地震&#xff08;平衡树&#xff09; COGS上一道题。。。文件名是equake 还是又打了一遍板子。。。 加个lazy标记就行了。。。 注意查询时先下传标记&#xff08;lazy&#xff09; // It is made by XZZ #include<cstdio> #include<algorithm> #de…