欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringDataJpa的使用之一對一、一對多、多對多?關(guān)系映射問題

 更新時間:2022年07月19日 11:38:07   作者:水沝淼?  
這篇文章主要介紹了SpringDataJpa的使用?--?一對一、一對多、多對多關(guān)系映射,本文主要講述?@OneToOne、@OneToMany、@ManyToOne、@ManyToMany?這四個關(guān)系映射注解的使用,以及其對應(yīng)的級聯(lián)關(guān)系,需要的朋友可以參考下

SpringDataJpa的使用 -- 一對一、一對多、多對多 關(guān)系映射

本文主要講述 @OneToOne、@OneToMany、@ManyToOne、@ManyToMany 這四個關(guān)系映射注解的使用,以及其對應(yīng)的級聯(lián)關(guān)系

有四張表,分別是:學(xué)生表、家長表、教室表、教師表,它們的關(guān)聯(lián)關(guān)系如下:

  • 學(xué)生 對 家長:一對一
  • 學(xué)生 對 教室:多對一
  • 學(xué)生 對 教師:多對多

項(xiàng)目依賴

必要的依賴有:mysql驅(qū)動、SpringBootWeb、SpringBootStarter、SpringDataJpa、SpringBootText、druid,其它的依賴可以按需添加。 如:lombok、

pom.xml 必要依賴

<!-- Spring Boot 都使用 2.4.5,看個人習(xí)慣 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.4.5</version>
<scope>runtime</scope>
</dependency>
<!-- Spring Data JPA 使用 2.6.1,看個人習(xí)慣 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.6.1</version>
</dependency>

<!-- mysql 驅(qū)動 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
<scope>runtime</scope>
</dependency>
<!-- druid 數(shù)據(jù)庫連接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.24</version>
</dependency>

pom.xml 可選依賴

<!--  Spring 熱部署  -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <version>2.4.5</version>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<optional>true</optional>
</dependency>

項(xiàng)目配置

application.yaml

spring:
  # DataSource
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: 賬號
    password: 密碼
    # serverTimezone可以設(shè)置為北京時間GMT%2B8、上海時間Asia/Shanghai或者香港時間Hongkong
    url: jdbc:mysql://localhost:3306/cloudtext?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
  # DataBase Connection -- JPA
  jpa:
    # 顯示 SQL 語句
    show-sql: true
    # 不允許在視圖階段 執(zhí)行 sql
    open-in-view: false

# 建議設(shè)置一個不常用的,避免沖突
server:
  # 項(xiàng)目端口號
  port: 8092
  # 項(xiàng)目路徑
  servlet:
    context-path: /jpa

sql文件(MySQL版)

cloudText.sql 僅結(jié)構(gòu)

-- ----------------------------
-- Table structure for classroom
-- ----------------------------
DROP TABLE IF EXISTS `classroom`;
CREATE TABLE `classroom` (
 `class_room_id` tinyint unsigned NOT NULL AUTO_INCREMENT COMMENT '班級主鍵',
 `class_room_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '班級名稱',
 `class_room_location` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '班級位置',
  `class_room_capacity` int unsigned DEFAULT NULL COMMENT '班級人數(shù)',
  `class_room_grade` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '班級年級',
 PRIMARY KEY (`class_room_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;

-- ----------------------------
-- Table structure for patriarch
-- ----------------------------
DROP TABLE IF EXISTS `patriarch`;
CREATE TABLE `patriarch` (
 `patriarch_id` tinyint unsigned NOT NULL AUTO_INCREMENT COMMENT '家長主鍵',
 `patriarch_name` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '家長姓名',
 `patriarch_age` int unsigned DEFAULT NULL COMMENT '家長年齡',
 `patriarch_sex` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '家長性別',
 `patriarch_phone` varchar(11) COLLATE utf8_bin DEFAULT NULL COMMENT '家長電話',
 `patriarch_address` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '家長住址',
 PRIMARY KEY (`patriarch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
 `student_id` tinyint unsigned NOT NULL AUTO_INCREMENT COMMENT '學(xué)生主鍵',
 `student_name` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '學(xué)生姓名',
 `student_age` int unsigned DEFAULT NULL COMMENT '學(xué)生年齡',
 `student_sex` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '學(xué)生性別',
 `patriarch_id` tinyint unsigned NOT NULL COMMENT '家長外鍵',
 `class_room_id` tinyint unsigned DEFAULT NULL COMMENT '班級外鍵',
 PRIMARY KEY (`student_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;

-- ----------------------------
-- Table structure for student_teacher
-- ----------------------------
DROP TABLE IF EXISTS `student_teacher`;
CREATE TABLE `student_teacher` (
 `student_id` tinyint unsigned NOT NULL COMMENT '學(xué)生主鍵',
 `teacher_id` tinyint unsigned NOT NULL COMMENT '教師主鍵',
 PRIMARY KEY (`student_id`,`teacher_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;


-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
 `teacher_id` tinyint unsigned NOT NULL AUTO_INCREMENT COMMENT '教師主鍵',
 `teacher_name` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '教師姓名',
 `teacher_age` int unsigned DEFAULT NULL COMMENT '教師年齡',
 `teacher_sex` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '教師性別',
 `teacher_course` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '教師教授科目',
 PRIMARY KEY (`teacher_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;

級聯(lián)關(guān)系簡述

  • ALL -- 級聯(lián)所有操作
  • PERSIST -- 級聯(lián)持久化操作
  • MERGE -- 級聯(lián)合并操作
  • REMOVE -- 級聯(lián)刪除操作
  • REFRESH -- 級聯(lián)刷新操作(調(diào)用refresh方法才會刷新)
  • DETACH -- 級聯(lián)分離操作(2.0版本才有)

參考:《Spring Boot 整合——JPA 數(shù)據(jù)模型關(guān)聯(lián)操作(一對一、一對多、多對多)》

參考:《cascade級聯(lián)關(guān)系》

@OneToOne 一對一 關(guān)系映射

一對一關(guān)系的雙方必須有且僅有一方放棄維護(hù),在 @OneToOne 中添加mappedBy屬性表示放棄維護(hù)。

學(xué)生類(Student.java):維護(hù)方 家長類(Patriarch.java):被維護(hù)方

Student.java (主鍵和非外鍵屬性)

package com.ljm.exmaple.entity;

import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * 學(xué)生 類
 *
 * @author LJM
 */
@Entity
@Table(name = "STUDENT")
public class Student {
	
	/**
	 * 學(xué)生 id
	 */
	@Id
	@Column(name = "student_id", nullable = false)
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long studentId;
	/**
	 * 學(xué)生 姓名
	 */
	@Column(name = "student_name", nullable = false)
	private String studentName;
	/**
	 * 學(xué)生 年齡
	 */
	@Column(name = "student_age", nullable = false)
	private Short studentAge;
	/**
	 * 學(xué)生 性別
	 */
	@Column(name = "student_sex", nullable = false)
	private String studentSex;
	/** 省略 Constructor、Getter、Setter、toString 方法 **/
}

Patriarch.java (主鍵和非外鍵屬性)

package com.ljm.exmaple.entity;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * 家長 類
 *
 * @author LJM
 */
@Entity
@Table(name = "PATRIARCH")
public class Patriarch {
    /**
     * 家長 id
     */
    @Id
    @Column(name = "patriarch_id", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long patriarchId;
    /**
     * 家長 姓名
     */
    @Column(name = "patriarch_name", nullable = false)
    private String patriarchName;
    /**
     * 家長 年齡
     */
    @Column(name = "patriarch_age")
    private Short patriarchAge;
    /**
     * 家長 性別
     */
    @Column(name = "patriarch_sex", nullable = false)
    private String patriarchSex;
    /**
     * 家長 電話
     */
    @Column(name = "patriarch_phone", nullable = false, length = 11)
    private String patriarchPhone;
    /**
     * 家長 住址
     */
    @Column(name = "patriarch_address", nullable = false)
    private String patriarchAddress;
    /** 省略 Constructor、Getter、Setter、toString 方法 **/
}

1.無中間表,維護(hù)方添加外鍵,被維護(hù)方添加對應(yīng)項(xiàng)

cascade = CascadeType.ALL 表示:級聯(lián)關(guān)系。

fetch = FetchType.EAGER 表示:預(yù)加載。

name = "patriarch_id" 指定外鍵。

nullable = false 表示:不能為空。

unique = true 表示:不能重復(fù)。

mappedBy = "patriarch" :添加了這個屬性表示放棄維護(hù)。

維護(hù)方的屬性添加到 Student.java 中。

被維護(hù)方的屬性添加到 Patriarch.java 中。

/**
 * 一對一
 * 家長 外鍵
 * 維護(hù)方   
 * 使用  CascadeType.ALL 亦可,區(qū)別不大
 */
@OneToOne(cascade = {CascadeType.MERGE, CascadeType.REMOVE}, fetch = FetchType.EAGER)
@JoinColumn(name = "patriarch_id", nullable = false, unique = true)
private Patriarch patriarch;


/**
 * 一對一
 * 被維護(hù)方(對應(yīng)項(xiàng))
 * 使用  CascadeType.ALL 亦可,區(qū)別不大
 */
@OneToOne(mappedBy = "patriarch", cascade = {CascadeType.REFRESH, CascadeType.MERGE, CascadeType.REMOVE}, fetch = FetchType.EAGER)
private Student student;

/** 注意,外鍵及對應(yīng)項(xiàng)的 Getter、Setter 不要忘了 */

2.無中間表,維護(hù)方添加外鍵,被維護(hù)方不添加對應(yīng)項(xiàng)

cascade = CascadeType.ALL 表示:級聯(lián)關(guān)系。

fetch = FetchType.EAGER 表示:預(yù)加載。

name = "patriarch_id" 指定外鍵。

nullable = false 表示:不能為空。

unique = true 表示:不能重復(fù)。

維護(hù)方的屬性添加到 Student.java 中。

/**
 * 一對一
 * 家長 外鍵
 * 維護(hù)方   
 * 使用  CascadeType.ALL 亦可,區(qū)別不大
 */
@OneToOne(cascade = {CascadeType.MERGE, CascadeType.REMOVE}, fetch = FetchType.EAGER)
@JoinColumn(name = "patriarch_id", nullable = false, unique = true)
private Patriarch patriarch;
/**
 * 一對一
 * 被維護(hù)方(對應(yīng)項(xiàng)),不需要添加對應(yīng)項(xiàng)
 * 使用  CascadeType.ALL 亦可,區(qū)別不大
 */
/**
 * @OneToOne(mappedBy = "patriarch", cascade = {CascadeType.REFRESH, CascadeType.MERGE, CascadeType.REMOVE}, fetch = FetchType.EAGER)
 * private Student student;
 */

/** 注意,外鍵的 Getter、Setter 不要忘了 */

3.有中間表,維護(hù)方不添加外鍵,被維護(hù)方不添加對應(yīng)項(xiàng)

暫缺,這不是本文重點(diǎn),以后可能會添加。

不需要使用關(guān)系注解 @OneToOne、@OneToMany、@ManyToOne、@ManyToMany,沒有外鍵。

@OneToMany、@ManyToOne 一對多 關(guān)系映射

一對多關(guān)系中,多方必須維護(hù)外鍵,一方一般不維護(hù)(我在某篇文章中看到:說一方也可以維護(hù)外鍵,我還未驗(yàn)證)。

學(xué)生類(Student.java):維護(hù)方

教室類(ClassRoom.java):被維護(hù)方

Student.java (主鍵和非外鍵屬性)

package com.ljm.exmaple.entity;

import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * 學(xué)生 類
 *
 * @author LJM
 */
@Entity
@Table(name = "STUDENT")
public class Student {
    /**
     * 學(xué)生 id
     */
    @Id
    @Column(name = "student_id", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long studentId;
    /**
     * 學(xué)生 姓名
     */
    @Column(name = "student_name", nullable = false)
    private String studentName;
    /**
     * 學(xué)生 年齡
     */
    @Column(name = "student_age", nullable = false)
    private Short studentAge;
    /**
     * 學(xué)生 性別
     */
    @Column(name = "student_sex", nullable = false)
    private String studentSex;
    /** 省略 Constructor、Getter、Setter、toString 方法 **/
}

ClassRoom.java (主鍵和非外鍵屬性)

package com.ljm.exmaple.entity;

import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * 教室 類
 *
 * @author LJM
 */
@Entity
@Table(name = "CLASSROOM")
public class ClassRoom {
    /**
     * 教室 id
     */
    @Id
    @Column(name = "classRoom_id", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long classRoomId;
    /**
     * 教室 名稱
     */
    @Column(name = "classRoom_name", nullable = false)
    private String classRoomName;
    /**
     * 教室 位置
     */
    @Column(name = "classRoom_location", nullable = false)
    private String classRoomLocation;
    /**
     * 教室 容量
     */
    @Column(name = "classRoom_capacity", nullable = false)
    private Short classRoomCapacity;
    /**
     * 教室 所在的 班級的年級(小學(xué)到高中)
     */
    @Column(name = "classRoom_grade", nullable = false)
    private String classRoomGrade;
    /** 省略 Constructor、Getter、Setter、toString 方法 **/
}

1.無中間表,多方維護(hù)并添加外鍵,一方被維護(hù)

cascade = CascadeType.XXX 表示:級聯(lián)關(guān)系。

fetch = FetchType.EAGER 表示:預(yù)加載。

name = "classRoom_id" 指定外鍵。

nullable = false 表示:不能為空。

mappedBy = "classRoom" :添加了這個屬性表示放棄維護(hù),在一對多的一方用來指向多方的那個外鍵屬性。

/**
 * 多對一
 * 多方
 * 教室外鍵
 * 維護(hù)方,級聯(lián)關(guān)系為 none(沒有,默認(rèn))
 */
@JoinColumn(name = "classRoom_id", nullable = false)
@ManyToOne(fetch = FetchType.EAGER)
private ClassRoom classRoom;


/**
 * 一對多
 * 一方
 * (被)維護(hù)方(對應(yīng)項(xiàng))
 * 被維護(hù)方代碼
 */
@OneToMany(mappedBy = "classRoom", cascade = {CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER)
private List<Student> studentList;

/** 注意,外鍵及對應(yīng)項(xiàng)的 Getter、Setter 不要忘了 */

2.有中間表,多方維護(hù),一方被維護(hù)

暫缺,這不是本文重點(diǎn),以后可能會添加。

不需要使用關(guān)系注解 @OneToOne、@OneToMany、@ManyToOne、@ManyToMany,沒有外鍵。

3.無中間表,多方維護(hù),一方也維護(hù)

暫缺,待驗(yàn)證。

@ManyToMany 多對多 關(guān)系映射

多對多關(guān)系中,必須有且僅有一方放棄維護(hù)外鍵,需要新建中間表,但不需要寫對應(yīng)的實(shí)體類。

學(xué)生類(Student.java):維護(hù)方

教師類(Teacher.java):被維護(hù)方

Student.java (主鍵和非外鍵屬性)

package com.ljm.exmaple.entity;

import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * 學(xué)生 類
 *
 * @author LJM
 */
@Entity
@Table(name = "STUDENT")
public class Student {	
    /**
     * 學(xué)生 id
     */
    @Id
    @Column(name = "student_id", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long studentId;
    /**
     * 學(xué)生 姓名
     */
    @Column(name = "student_name", nullable = false)
    private String studentName;
    /**
     * 學(xué)生 年齡
     */
    @Column(name = "student_age", nullable = false)
    private Short studentAge;
    /**
     * 學(xué)生 性別
     */
    @Column(name = "student_sex", nullable = false)
    private String studentSex;
    /** 省略 Constructor、Getter、Setter、toString 方法 **/
}

Teacher.java (主鍵和非外鍵屬性)

package com.ljm.exmaple.entity;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
/**
 * 教師 類
 *
 * @author LJM
 */
@Entity
@Table(name = "TEACHER")
public class Teacher {
    /**
     * 教師 id
     */
    @Id
    @Column(name = "teacher_id", nullable = false)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long teacherId;
    /**
     * 教師 姓名
     */
    @Column(name = "teacher_name", nullable = false)
    private String teacherName;
    /**
     * 教師 年齡
     */
    @Column(name = "teacher_age")
    private Integer teacherAge;
    /**
     * 教師 性別
     */
    @Column(name = "teacher_sex", nullable = false)
    private String teacherSex;
    /**
     * 教師 所教的 科目
     */
    @Column(name = "teacher_course", nullable = false)
    private String teacherCourse;
    /** 省略 Constructor、Getter、Setter、toString 方法 **/
}

fetch = FetchType.EAGER 表示:預(yù)加載。

name = "student_teacher" 指定關(guān)聯(lián)關(guān)系表。

joinColumns = @JoinColumn(name = "student_id") 指定我方在關(guān)聯(lián)表中對應(yīng)的主鍵。

inverseJoinColumns = @JoinColumn(name = "teacher_id") 指定被維護(hù)方在關(guān)聯(lián)表中對應(yīng)的主鍵。

mappedBy = "teacherList" :添加了這個屬性表示放棄維護(hù),維護(hù)方用來指向另一方的那個外鍵屬性。

/**
 * 多對多
 * 維護(hù)方
 * 教師 外鍵
 * 級聯(lián)關(guān)系為 none(沒有,默認(rèn)),雙方互不干擾
 */
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "student_teacher", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "teacher_id"))
private List<Teacher> teacherList;


/**
 * 多對多
 * 被維護(hù)方
 * 學(xué)生 外鍵(對應(yīng)項(xiàng))
 * 級聯(lián)關(guān)系為 none(沒有,默認(rèn)),雙方互不干擾
 */
@ManyToMany(mappedBy = "teacherList", fetch = FetchType.EAGER)
private List<Student> studentList;

/** 注意,外鍵及對應(yīng)項(xiàng)的 Getter、Setter 不要忘了 */

本文參考

Spring Data JPA之一對一,一對多,多對多關(guān)系映射

到此這篇關(guān)于SpringDataJpa的使用之一對一、一對多、多對多 關(guān)系映射的文章就介紹到這了,更多相關(guān)SpringDataJpa使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論