SpringBoot——》关联映射

推荐链接:
    总结——》【Java】
    总结——》【Mysql】
    总结——》【Redis】
    总结——》【Kafka】
    总结——》【Spring】
    总结——》【SpringBoot】
    总结——》【MyBatis、MyBatis-Plus】
    总结——》【Linux】
    总结——》【MongoDB】
    总结——》【Elasticsearch】

SpringBoot——》关联映射

  • 一、场景
  • 二、关联映射
    • 1、@OneToOne(一对一)
      • 实现一:@JoinColumn
      • 实现二:@PrimaryKeyJoinColumn
      • 实现三:不使用@JoinColumn和@PrimaryKeyJoinColumn
    • 2、@OneToMany(一对多)
      • 实现一:@JoinColumn
      • 实现二:@JoinTable
      • 实现三:不使用@JoinColumn
    • 3、@ManyToOne(多对一)
      • 实现一:@JoinColumn
    • 4、@ManyToMany(多对多)
      • 实现一:@JoinTable
  • 三、完整示例
    • 1、员工实体类:Employee.java
    • 2、地址实体类:Address.java
    • 3、部门实体类:Department.java
    • 4、角色实体类:Role.java

一、场景

以员工、地址、部门、角色四者之间的关联关系为例:

  1. 一个员工只能有一个地址,一个地址也只属于一个员工;
  2. 一个员工只能属于一个部门,但是一个部门可以包含有多个员工;
  3. 一个员工可以拥有多个角色,一个角色也可以属于多个员工。
实体类描述备注
tb_employeeEmployee员工一个员工只能有一个地址
一个员工只能属于一个部门
一个员工可以拥有多个角色
tb_addressAddress地址一个地址只属于一个员工
tb_departmentDepartment部门一个部门可以包含有多个员工
tb_roleRole角色一个角色也可以属于多个员工

二、关联映射

由于 @OneToOne(一对一)、@OneToMany(一对多)、@ManyToOne(多对一)、@ManyToMany(多对多) 等注解只能确定实体之间几对几的关联关系,它们并不能指定与实体相对应的数据库表中的关联字段,因此,需要与 @JoinColumn 注解来配合使用。

1、@OneToOne(一对一)

实现一:@JoinColumn

在员工表中会有一个指向地址表主键的字段address_id

// 一个员工只能有一个地址,在员工实体类中添加如下注解:@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "address_id")
private Address address;

实现二:@PrimaryKeyJoinColumn

如果员工表和地址表是以主键关联的:

  • 员工表主键:employee_id
  • 地址表主键:address_id
// 一个员工只能有一个地址,在员工实体类中添加如下注解:@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn(name = "employee_id", referencedColumnName = "address_id")
private Address address;

实现三:不使用@JoinColumn和@PrimaryKeyJoinColumn

Hibernate会自动在员工表生成关联字段,字段默认的命名规则:被控方类名_被控方主键,如:address_id

// 一个员工只能有一个地址,在员工实体类中添加如下注解:@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
// Hibernate会自动在员工表生成关联字段,字段默认的命名规则:被控方类名_被控方主键,如:address_id
private Address address;

2、@OneToMany(一对多)

一个员工只能属于一个部门,但是一个部门可以包含有多个员工,如果我们站在部门的角度来看,部门与员工之间就是一对多的关系。

实现一:@JoinColumn

// 一个部门可以包含有多个员工,在部门实体类中添加如下注解:@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "department_id")
private List<Employee> employees;

实现二:@JoinTable

// 一个部门可以包含有多个员工,在部门实体类中添加如下注解:@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
/**
* joinColumns 用来指定中间表中关联自己ID的字段 
* inverseJoinColumns 用来指定中间表中关联对方ID的字段
*/
@JoinTable(name = "tbl_employee_department", joinColumns = {
@JoinColumn(name = "department_id") }, inverseJoinColumns = { @JoinColumn(name = "employee_id") })
private List<Employee> employees;

实现三:不使用@JoinColumn

Hibernate会自动生成一张中间表来对员工和部门进行绑定,表名默认的命名规则:一的表名_一实体类中关联多的属性名,例如,部门表名为 tb_department ,部门实体中关联的员工集合属性名为 employees ,则生成的中间表名为:tb_department_employees。
通常并不推荐让Hibernate自动去自动生成中间表,而是使用@JoinTable注解来指定中间表。

3、@ManyToOne(多对一)

实现一:@JoinColumn

// 一个部门可以包含有多个员工,但一个员工只能属于一个部门,在员工实体类中添加如下注解:@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "department_id")
private Department department;

4、@ManyToMany(多对多)

一个员工可以拥有多个角色,一个角色也可以属于多个员工,员工与角色之间就是多对多的关系。通常这种多对多关系都是通过创建中间表来进行关联处理,并使用@JoinTable注解来指定。

实现一:@JoinTable

// 一个员工可以拥有多个角色,在员工实体类中添加如下注解:@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "tb_employee_role", joinColumns = { @JoinColumn(name = "employee_id") }, inverseJoinColumns = {
@JoinColumn(name = "role_id") })
private List<Role> roles;
// 一个角色可以属于多个员工,在角色实体类中添加如下注解:@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "tb_employee_role", joinColumns = { @JoinColumn(name = "role_id") }, inverseJoinColumns = {@JoinColumn(name = "employee_id") })
private List<Employee> employees;

三、完整示例

1、员工实体类:Employee.java

@Entity
@Table(name = "tb_employee")
@Comment("员工")
@Data
public class Employee {@Id@GeneratedValue(generator = "seq_employee_id")@SequenceGenerator(name = "seq_employee_id", sequenceName = "seq_employee_id")private Long id;@Column(name = "name", columnDefinition = "varchar(64) COMMENT '名称'", nullable = false)private String name;@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)@JoinColumn(name = "address_id", columnDefinition = "bigint(20) COMMENT '地址ID'", nullable = false)// @PrimaryKeyJoinColumn(name = "employee_id", referencedColumnName = "address_id")private Address address;@Getter@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)@JoinColumn(name = "department_id")private Department department;@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)@JoinTable(name = "tb_employee_role",joinColumns = {@JoinColumn(name = "employee_id")},inverseJoinColumns = {@JoinColumn(name = "role_id")})private List<Role> roles; // 角色
}

2、地址实体类:Address.java

@Entity
@Table(name = "tb_address")
@Comment("地址")
@Data
public class Address {@Id@GeneratedValue(generator = "seq_address_id")@SequenceGenerator(name = "seq_address_id", sequenceName = "seq_address_id")private Long id;@Column(name = "address", columnDefinition = "varchar(64) COMMENT '地址'", nullable = false)private String address;
}

3、部门实体类:Department.java

@Entity
@Table(name = "tb_department")
@Comment("部门")
@Data
public class Department {@Id@GeneratedValue(generator = "seq_department_id")@SequenceGenerator(name = "seq_department_id", sequenceName = "seq_department_id")private Long id;@Getter@Column(name = "name", columnDefinition = "varchar(64) COMMENT '名称'", nullable = false)private String name;@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)@JoinColumn(name = "department_id")/*** joinColumns 用来指定中间表中关联自己ID的字段* inverseJoinColumns 用来指定中间表中关联对方ID的字段*/
//    @JoinTable(name = "tb_employee_department",
//            joinColumns = {@JoinColumn(name = "department_id", referencedColumnName = "id")},
//            inverseJoinColumns = {@JoinColumn(name = "employee_id", referencedColumnName = "id")})private List<Employee> employees;
}

4、角色实体类:Role.java

@Entity
@Table(name = "tb_role")
@Comment("角色")
@Data
public class Role {@Id@GeneratedValue(generator = "seq_role_id")@SequenceGenerator(name = "seq_role_id", sequenceName = "seq_role_id")private Long id;@Column(name = "name", columnDefinition = "varchar(64) COMMENT '名称'", nullable = false)private String name;@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)@JoinTable(name = "tb_employee_role",joinColumns = {@JoinColumn(name = "role_id")},inverseJoinColumns = {@JoinColumn(name = "employee_id")})private List<Employee> employees; // 拥有角色的员工
}

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

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

相关文章

移动机器人路径规划(七)--- 基于MDP的路径规划MDP-Based Planning

目录 1 什么是MDP-Based Planning 2 worst-case analysis for nondeterministic model 3 Expected Cost Planning 4 Real Time Dynamic Programming&#xff08;RTDP&#xff09; 1 什么是MDP-Based Planning 之前我们从起点到终点存在很多可执行路径&#xff0c;我们可以…

Can‘t find libdevice directory ${CUDA_DIR}/nvvm/libdevice

win10 Running deepxde 的时候出现问题&#xff1a; cuda-nvcc 安装后解决了。 # Install NVCC conda install -c nvidia cuda-nvcc11.3.58 -y # Configure the XLA cuda directory mkdir -p $CONDA_PREFIX/etc/conda/activate.d printf export LD_LIBRARY_PATH$LD_LIBRARY_P…

Python实现一箭穿心

文章目录 &#x1f384;效果&#x1f3f3;️‍&#x1f308;Turtle模块&#x1f339;代码&#x1f33a;代码讲解 &#x1f384;效果 &#x1f3f3;️‍&#x1f308;Turtle模块 Turtle是一个绘图工具&#xff0c;是Python标准库中的一个模块。它提供了一种简单而直观的方式来创…

【C++】内存管理(new与delete)

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 前言 本篇文章我们一起来学习C的内存管理方式&…

最新yolov8环境搭建、推理训练一站式超详细教学

1、获取yolov8源码 访问yolov8_github官网&#xff0c;网络不稳定时可能需要加速器。yolov8源码地址 获取方式&#xff1a;直接下载或者git工具克隆 我使用git操作进行演示&#xff0c;复制github上的地址(需提前关闭加速器)。 git clone https://github.com/ultralytics/ul…

【QML】Qt设置USB免驱相机曝光时间(Linux系统)UVC

1. 问题 使用QML的Camera组件创建相机。需要配置曝光时间&#xff0c;使用CameraExposure中的exposureCompensation&#xff0c;exposureMode配置无效果&#xff0c;原因可能是不支持USB相机。 有两种方法经测试有效果&#xff1a; 命令行调用v4l2-ctl命令的方法&#xff0c…

【XSLVGL2.0】如何做全局键功能和键值映射

XSLVGL2.0 开发手册 【XSLVGL2.0】如何做全局键功能和键值映射 1、概述1、概述 项目常见需要配置一个按键,并要求短按此按键回到首页, 长按此按键进行关机。 XSLVGL2.0在输入设备对接接口中,有一个回调,在此回调中可以直接收到输入设备上报的所有按键事件。 一般这个功能…

UI自动化(selenium+python)之元素定位的三种等待方式!

前言 在UI自动化过程中&#xff0c;常遇到元素未找到&#xff0c;代码报错的情况。这种情况下&#xff0c;需要用等待wait。 在selenium中可以用到三种等待方式即sleep,implicitly_wait,WebDriverWait 一、固定等待(sleep) 导入time模块&#xff0c;设定固定的等待时间 缺…

计数问题+约瑟夫问题(map)

目录 一、计数问题 二、约瑟夫问题 一、计数问题 #include<iostream> #include<map> using namespace std; int main() {int n,x;cin>>n>>x;map<int,int>m;for(int i1;i<n;i){if(i>1 && i<10){m[i];}else{int temp i;while (…

解决github无法访问的办法

方法/步骤 1.问题描述&#xff1a;能联网但不能访问github.com 2.找到hosts文件。地址&#xff1a;C:\Windows\System32\drivers\etc &#xff08;一般是在这的&#xff09; 3.不要直接在这修改hosts文件&#xff0c;需要将hosts文件复制粘贴到桌面&#xff08;或其它地方自…

【仿写实现move函数】

仿写实现move函数 一、值的类型 1.左值 描述&#xff1a;能够取地址的值成为左值 int a 10; const int b 15; int *pa &a; const int *pb &b;2.纯右值 描述&#xff1a;赤裸裸的字面值 eg(false , 3 , 12.23等) int a 13; int *p &a; //取a的地址 int …

在线音频视频剪辑网站推荐

123apps: Online MP3 Cutter - Cut Songs, Make Ringtones

Datax安装部署及读取MYSQL写入HDFS

一.DataX简介 1.DataX概述 DataX 是阿里巴巴开源的一个异构数据源离线同步工具&#xff0c;致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。 源码地址&#xff1a;https://github.com/alibaba/Data…

leaflet对线设置渐变色

效果展示&#xff1a; 引用leaflet-polycolor组件 npm install leaflet-polycolor .vue文件中使用 import leafletPolycolor from leaflet-polycolor; leafletPolycolor(L); const latLngs [[37.03, 111.92], [37.53444, 111.98555], [36.88, 112.12], [37.53444, 112.24], […

MT6893_天玑 1200芯片规格参数介绍_datasheet规格书

天玑 1200(MT6893)是一款专为旗舰级全新5G芯片&#xff0c;它融合了先进的AI、相机和多媒体技术&#xff0c;为用户带来令人惊叹的体验。采用先进的6纳米制程设计&#xff0c;内置各种先进技术。该芯片采用旗舰级的八核CPU架构设计&#xff0c;支持16GB强大的四通道内存以及双通…

CDN 加速 - 隐藏真实 IP - 复活 IP

CDN 一词相信很多朋友都不会陌生,网上也经常会看到相关报道。或许大部分人都知道 CDN 加速可以提升网站的打开速度及用户下载资源的速度,而同时也有不少朋友还不清楚 CDN 是什么?有什么用途?它是如何实现加速的呢?下面为大家整理了一些通俗易懂的知识点。 顺哥轻创 CDN …

每日一练:“打家劫舍“(House Robber)问题 II

有想要了解打家劫舍初级问题的&#xff0c;可以点击下面链接查看&#xff01; 每日一练&#xff1a;“打家劫舍“&#xff08;House Robber&#xff09;问题 I 1. 问题 假设有房屋形成一个环形&#xff0c;即第一个房屋和最后一个房屋也相邻&#xff0c;每个房屋里都存放着一定…

Leetcode—83.删除排序链表中的重复元素【简单】

2023每日刷题&#xff08;四十&#xff09; Leetcode—83.删除排序链表中的重复元素 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* deleteDuplicates(struct ListNode* head) {i…

c#处理SQLSERVER 中image数量类型为空

项目场景&#xff1a; DataRow dataRow dataTable.Rows[i]; var pxpicture dataRow ["pxImage"];if (pxpicture!null){byte[] pic (byte[])pxpicture;acs.Add("pxpicture", Convert.ToBase64String(pic));}问题描述 代码执行出现错误&#xff1a; 无…

MySQL 执行计划分析

MySQL执行计划最核心字段是 type 字段&#xff0c;用于描述优化器在执行查询时查找记录的方式。 其字段值较多&#xff0c;可分为 3 类加以理解&#xff1a;全表查询、范围查询、等值查询 全表查询 All&#xff1a;全表扫描&#xff0c;MySQL会扫描整个聚簇索引来找到匹配的行…