JPA 一對一 一對多 多對一 多對多配置


JPA概述

1.1 JPA是什么

JPA Java Persistence API Java持久化API。是一套Sun公司 Java官方制定的ORM 方案,是規范,是標准 ,sun公司自己並沒有實現

 

關注點: ORM  ,標准 概念 (關鍵字)

 

1.1.1 ORM是什么

 

ORMObject Relational Mapping 對象關系映射。

問:ORM有什么用?

在操作數據庫之前,先把數據表與實體類關聯起來。 然后通過實體類的對象操作(增刪改查)數據庫表,這個就是ORM的行為! 

所以:ORM是一個實現使用對象操作數據庫的設計思想!!! 

通過這句話,我們知道JPA的作用就是通過對象操作數據庫的,不用編寫sql語句

 

1.2 JPA的實現者

既然我們說JPA是一套標准,意味着,它只是一套實現ORM理論的接口。沒有實現的代碼。 

那么我們必須要有具體的實現者才可以完成ORM操作功能的實現! 

  

市場上的主流的JPA框架 (實現者)有: 

Hibernate JBoos)、EclipseTopEclipse社區)、OpenJPA Apache基金會)。 

  

其中Hibernate是眾多實現者之中,性能最好的。所以,我們本次教學也是選用Hibernate框架作為JPA的主講框架。 

提醒: 學習一個JPA框架,其他的框架都是一樣使用

1.3 JPA的作用是什么(問題)

JPAORM的一套標准,既然JPAORM而生,那么JPA的作用就是實現使用對象操作數據庫,不用寫SQL!!!. 

 

問題:數據庫是用sql操作的,那用對象操作,由誰來產生SQL 

答:JPA實現框架 

入門示例

任何框架的學習,都建議從配置流程圖開始。所以我們來一起理解JPA的配置流程圖。 

 

2.1 配置流程圖

 

 

1. 我們需要一個總配置文件persistence.xml存儲框架需要的信息 (注意,文件名不要寫錯,而且必須放在classpath/META-INF文件夾里面) 

2. 我們需要一個Persistence持久類對象來讀取總配置文件,創建實體管理工廠對象 

3. 我們需要實體管理工廠獲得數據庫的操作對象實體管理對象EntityManager 

4. 我們通過EntityManager操作數據庫之前,必須要先配置表與實體類的映射關系,從而實現使用對象操作數據庫!!!

 

2.2 配置步驟說明 

第一步:導入包 (不管什么框架,首先要做的事情) 

第二步:創建一個總配置文件 

第三步:創建一個JPAUtils獲得操作對象EntityManager 

第四步:創建一個實體類,並且配置好映射注解 

第五步:在總配置文件加載實體類 

第六步:測試代碼(需求:插入數據到用戶表) 

2.3 配置步驟 

 需求:編寫一個JPA的項目,插入一條數據到學生信息表。 

2.3.1 第一步:創建Maven項目

 

說明:我們這里是基於hibernate實現的,所以要導入HibernateJPA規范包

--使用maven構建的配置-- 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelVersion>4.0.0</modelVersion>

  <groupId>cn.zj</groupId>

  <artifactId>jpa-demo01-start</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  

  <dependencies>

    <!-- hibernate框架 實現 JPA 依賴 -->

<dependency>

    <groupId>org.hibernate</groupId>

    <artifactId>hibernate-entitymanager</artifactId>

    <version>4.3.6.Final</version>

</dependency>

    <!--jdbc驅動 -->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>5.1.40</version>

</dependency>

  </dependencies>

</project>

 

2.3.2 第二步創建一個總配置文件

注意:文件必須放在classpath:/META-INF/persistence.xml 

 

說明:Eclipse已經支持了JPA框架,所有不需要配置xsd文件,直接使用

 

 

 

配置信息如下

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd ">

  <persistence-unit name="mysql-jpa">

   <!-- 四要素 org.hibernate.cfg.Environment--> 

<properties> 

     <!-- 如果使用Hibernate實現的JPA,使用的就是Hibernate的環境參數 --> 

<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> 

<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa" /> 

<property name="hibernate.connection.username" value="root" /> 

<property name="hibernate.connection.password" value="root" /> 

<!--可選配置--> 

<!--控制台打印sql語句--> 

<property name="hibernate.show_sql" value="true" /> 

    <!-- 格式化輸出SQL --> 

<property name="hibernate.format_sql" value="true" /> 

</properties> 

  </persistence-unit>

</persistence>

 

2.3.3 第三步:封裝JPAUtils工具類

創建一個工具類JPAUtils,獲得操作對象(EntityManager 

package cn.zj.jpa.util;

 

import javax.persistence.EntityManager;

import javax.persistence.EntityManagerFactory;

import javax.persistence.Persistence;

 

public class JPAUtils {

 

//同一個應用中,應該保證只有一個實例工廠。

public static EntityManagerFactory emf = createEntityManagerFactory();

 

//1.獲得實體管理工廠

private static EntityManagerFactory createEntityManagerFactory(){

EntityManagerFactory emf = Persistence.createEntityManagerFactory("mysql-jpa");

return emf;

}

 

    //2.獲得實體管理類對象

public static EntityManager getEntityManger(){

EntityManager entityManager = emf.createEntityManager();

return entityManager;

}

}

 

2.3.4 第四步創建映射實體類

創建一個映射的實體類,將JPA的映射注解寫在實體類里面。 

package cn.zj.jpa.entity;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.Table;

 

//1.指定實體類與表名的關系

//@Entity注解,指定該實體類是一個基於JPA規范的實體類

@Entity 

//@Table注解,指定當前實體類關聯的表

@Table(name="tb_student")

public class Student {

//@Id注解:聲明屬性為一個OID屬性

@Id 

//@GeneratedValue注解,指定主鍵生成策略

@GeneratedValue(strategy=GenerationType.IDENTITY)

//@Column注解,設置屬性與數據庫字段的關系,如果屬性名和表的字段名相同,可以不設置

@Column(name="stu_id")

private Long stuId;//BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '學生編號',

@Column(name="stu_name")

private String stuName;//VARCHAR(50) NULL DEFAULT NULL COMMENT '學生名字',

@Column(name="stu_age")

private Integer stuAge;//INT(11) NULL DEFAULT NULL COMMENT '學生年齡',

@Column(name="stu_password")

private String stuPassword;//VARCHAR(50) NULL DEFAULT NULL COMMENT '登錄密碼',

   

public Student() {

super();

}

//補全get、set方法

}

 

2.3.5 第五步:在總配置文件中加載映射實體類

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd ">

  <persistence-unit name="mysql-jpa">

  

  <!-- 加載實體類

   基於hibernate框架的JPA已經實現了自動載入映射實體類 ,所以不配置也是可以的。建議還是加上配置。如果不寫容易忽略加載的實體類有哪些

     -->

    <class>cn.zj.jpa.entity.Student</class>

   <!-- 四要素 org.hibernate.cfg.Environment--> 

<properties> 

     <!-- 如果使用Hibernate實現的JPA,使用的就是Hibernate的環境參數 --> 

<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> 

<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa" /> 

<property name="hibernate.connection.username" value="root" /> 

<property name="hibernate.connection.password" value="zj" /> 

<!--可選配置--> 

<!--控制台打印sql語句--> 

<property name="hibernate.show_sql" value="true" /> 

    <!-- 格式化輸出SQL --> 

<property name="hibernate.format_sql" value="true" /> 

</properties> 

  </persistence-unit>

</persistence>

 

2.3.6 第六步:操作實體類保存數據

創建一個StudentDAOTest類,測試保存一個學生。

package cn.zj.jpa;

 

import javax.persistence.EntityManager;

import javax.persistence.EntityTransaction;

import org.junit.Test;

import cn.zj.jpa.entity.Student;

import cn.zj.jpa.util.JPAUtils;

 

public class StudentDAOTest {

 

@Test

public void persist(){

//1.獲得實體管理類

EntityManager manager = JPAUtils.getEntityManger();

//2、獲取事物管理器

EntityTransaction transaction = manager.getTransaction();

transaction.begin();

//3、創建實體對象

Student s=new Student();

s.setStuName("張三");

s.setStuAge(18);

s.setStuPassword("zj");

//4、保存到數據庫

manager.persist(s);

//5、提交事物

transaction.commit();

//6、關閉資源

manager.close();

}

}

 

測試結果

 

 

通過操作實體對象保存數據成功!!!

 

2.4 使用JPA的好處

使用JPA,可以直接使用對象操作數據庫,由框架根據映射的關系生成SQL。不用開發人員編寫。這樣做,開發人員就不用編寫SQL語句了

  

問題:這樣有什么好處呢? 

 

答:不同的數據庫的SQL語法是有差異,如果不需要編寫SQL語句。就屏蔽各種數據庫SQL的差異。那么,編寫的代碼就可以一套代碼兼容多種數據庫!!!! 

 

JPA實現CRUD

修改StudentDAOTest類,測試crud操作

//通過OID刪除

@Test

public void remove(){

//1.獲得實體管理類對象

EntityManager entityManager = JPAUtils.getEntityManger();

//2.打開事務

EntityTransaction transaction = entityManager.getTransaction();

//3.啟動事務

transaction.begin();

//4.創建數據,刪除數據必須使用持久化對象

Student s=entityManager.find(Student.class, 2L);

 

//5.插入

entityManager.remove(s);;

//6。提交

transaction.commit();

//7.關閉

entityManager.close();

}

 

 

//更新

@Test

public void merge(){

//1.獲得實體管理類對象

EntityManager entityManager = JPAUtils.getEntityManger();

//2.打開事務

EntityTransaction transaction = entityManager.getTransaction();

//3.啟動事務

transaction.begin();

//4.創建數據

Student s=new Student();

s.setStuName("李四");

//更新必須要有一個OID

s.setStuId(3L);

//5.更新

entityManager.merge(s);

//6。提交

transaction.commit();

//7.關閉

entityManager.close();

 

}

 

//通過OID獲得數據

@Test

public void find(){

//1.獲得實體管理類對象

EntityManager entityManager = JPAUtils.getEntityManger();

//通過OID查詢數據

Student student = entityManager.find(Student.class, 1L);

System.out.println(student.getStuName());

entityManager.close();

}

 

//通過OID獲得數據

@Test

public void getReference(){

//1.獲得實體管理類對象

EntityManager entityManager = JPAUtils.getEntityManger();

/**

 * getReference()find()方法的區別:

 * getReference基於懶加載機制,即需要使用對象的時候,才執行查詢。

 */

Student student = entityManager.getReference(Student.class, 1L);

System.out.println(student.getStuName());

entityManager.close();

}

JPA常用 API說明

4.1 映射注解說明

注解

說明

@Entity

聲明該實體類是一個JPA標准的實體類

@Table

指定實體類關聯的表,注意如果不寫表名,默認使用類名對應表名。

@Column

指定實體類屬性對應的表字段,如果屬性和字段一致,可以不寫

@Id

聲明屬性是一個OID,對應的一定是數據庫的主鍵字段

@GenerateValue

聲明屬性(Object ID)的主鍵生成策略

@SequenceGenerate

使用SEQUENCE策略時,用於設置策略的參數

@TableGenerate

使用TABLE主鍵策略時,用於設置策略的參數

@JoinTable

關聯查詢時,表與表是多對多的關系時,指定多對多關聯表中間表的參數。

@JoinColumn

關聯查詢時,表與表是一對一、一對多、多對一以及多對多的關系時,聲明表關聯的外鍵字段作為連接表的條件。必須配合關聯表的注解一起使用 <key>

@OneToMany

關聯表注解,表示對應的實體和本類是一對多的關系

@ManyToOne

關聯表注解,表示對應的實體和本類是多對一的關系

@ManyToMany

關聯表注解,表示對應的實體和本類是多對多的關系

@OneToOne

關聯表注解,表示對應的實體和本類是一對一的關系

 

4.2 JPA常用API說明

API

說明

Persistence

用於讀取配置文件,獲得實體管理工廠

EntityManagerFactory

用於管理數據庫的連接,獲得操作對象實體管理類

EntityManager

實體管理類,用於操作數據庫表,操作對象

EntityTransaction

用於管理事務。開始,提交,回滾

TypeQuery

用於操作JPQL查詢的

Query

用於操作JPQL的查詢接口,執行沒有返回數據的JPQL(增刪改)

CriteriaBuilder

用戶使用標准查詢接口 Criteria查詢接口

 

JPA多表關聯查詢 

多個關聯查詢作用(導航查詢):就是實現使用一個實體類對象查詢多個表的數據。 

  配置多表聯系查詢必須有兩個步驟; 

1)、在實體類里面建立表與表之間的關系。 

2)、在實體類配置關聯關系,JPA使用注解配置 

 

多表關聯的E-R如下

 

 

根據ER圖,創建數據庫表!!!

 

5.1 一對多實現 (單向)

需求:通過ID查詢一條學生表的記錄,同時查詢該學生的對應的成績的信息!

 

5.1.1 說明

如圖所示:一個學生可以有多條成績的記錄,一條成績的記錄只屬於一個學生,所以學生表與成績表的關系是一對多的關系。

 

 

 

所以,通過JPA配置一對多的關系,可以通過學生表對應的實體類對象同時獲得兩個表的數據。

 

5.1.2 配置步驟

5.1.2.1 第一步創建項目

說明:復制入門示例的項目即可。

 

5.1.2.2 第二步:創建單表實體類

1)創建Student

@Entity 

@Table(name="tb_student")

public class Student {

@Id 

@GeneratedValue(strategy=GenerationType.IDENTITY)

@Column(name="stu_id")

private Long stuId;

@Column(name="stu_name")

private String stuName;

@Column(name="stu_age")

private Integer stuAge; 

@Column(name="stu_password")

private String stuPassword;

   

public Student() {

super();

}

//補全get、set方法

}

 

2)創建Score

@Entity

@Table(name="tb_score")

public class Score{

 

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

@Column(name="sco_id")

private Long scoId;  

@Column(name="sco_subject")

private String scoSubject;

@Column(name="sco_score")

private Float scoScore;

@Column(name="stu_id")

private Long stuId;

 

public Score() {

super();

}

// 補全getset方法

}

 

5.1.2.3 第三步:配置一對多關聯關系

說明:通過@OneToMany注解配置。

 

修改Student類,配置一對多關系。

/**

 * 單向一對對,應該有學生來維護關系

 *

 * 一個學生對應多個成績,一對多關系

 * 多個成績我們使用list封裝起來

 *

 * JPA 使用 @OneToMany 映射一對多

 * fetch : 抓取策略

 * FetchType.LAZY 懶加載,默認 (只有關聯對象在用到的時候才會去發送新的sql,默認關聯對象不會查詢)

 * 會多生成sql語句 :N+1

 * FetchType.EAGER 迫切查詢 (多表連接查詢,只會發送一條sql語句)

 * @JoinColumn 設置兩張表之間外鍵列

 */

@OneToMany(fetch=FetchType.EAGER)

@JoinColumn(name="stu_id")

private List<Score> scores;

public void setScores(List<Score> scores) {

this.scores = scores;

}

5.1.2.4 第四步:測試一對多查詢

@Test

public void testOne2Many(){

//1.獲得實體管理類

EntityManager manager = JPAUtils.getEntityManger();

 

Student student = manager.find(Student.class, 1L);

System.out.println("學生id:"+student.getStuId()+",學生姓名:"+student.getStuName());

 

List<Score> scores = student.getScores();

for (Score score : scores) {

System.out.println("科目:"+score.getScoSubject()+",分數:"+score.getScoScore());

}

 

//6、關閉資源

manager.close();

}

 

查詢結果:

 

 

 

一對多關聯查詢成功!!!

 

5.2 多對一實現 (單向)

5.2.1 說明

需求:通過ID查詢一條成績表的記錄,同時查詢該成績的對應的學生的信息! 

 

如圖所示:成績表里面,每一條記錄只能對應一個學生,但是學生編號不是唯一的。所以成績表里面的多條數據可以對應一個學生,所以我們稱多對一的關系。

 

 

 

 

5.2.2 配置步驟

5.2.2.1 第一步創建項目

復制一對多示例項目即可。

 

5.2.2.2 第二步:創建單表實體類

修改Student類,去掉一對多配置即可。

 

5.2.2.3 第三步:配置多對一關聯關系

修改Score類,配置多對一關系

@Entity

@Table(name="tb_score")

public class Score{

 

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

@Column(name="sco_id")

private Long scoId;  

 

@Column(name="sco_subject")

private String scoSubject;

 

@Column(name="sco_score")

private Float scoScore;

 

/**

 * jpa的多對一,關聯關系中指定的外鍵  和 關聯表的屬性有沖突  

 *    解決的方案:去掉關聯表中外鍵對應的屬性

 

/*@Column(name="stu_id")

private Long stuId;

 

public Long getStuId() {

return stuId;

}

 

public void setStuId(Long stuId) {

this.stuId = stuId;

}

*/

 

/**

 * 1、分數和學生信息是多對一的關系

 * 2、只需要一個學生的實體來引用學生的信息

 */

@ManyToOne

@JoinColumn(name="stu_id")

private Student student;

 

public Student getStudent() {

return student;

}

public void setStudent(Student student) {

this.student = student;

}

//補全getset方法

}

 

5.2.2.4 第四步:測試

@Test

public void testMany2One(){

//1.獲得實體管理類

EntityManager manager = JPAUtils.getEntityManger();

 

Score score = manager.find(Score.class, 1L);

System.out.println("科目:"+score.getScoSubject()+",分數:"+score.getScoScore());

 

Student student = score.getStudent();

System.out.println("學生id:"+student.getStuId()+",學生姓名:"+student.getStuName());

//6、關閉資源

manager.close();

}

 

查詢結果:

 

 

 

多對一配置成功!!!

 

5.3 雙向一對多|多對一(了解)

5.3.1 說明

1查詢學生信息同時查詢成績信息

2)查詢成績信息,同時也可以查詢學生信息。

5.3.2 配置步驟

在同一個項目中Student類和Score類中,同時配置關聯關系。

 

1)在Student類中配置一對多

@OneToMany   //聲明是一對多的關系

@JoinColumn(name="stu_id")   //指定關聯表中  外鍵的字段

private List<Score> scores;

 

public List<Score> getScores() {

return scores;

}

 

public void setScores(List<Score> scores) {

this.scores = scores;

}

 

2)在Score類中配置多對一

/**

 * jpa的多對一,關聯關系中指定的外鍵  和 關聯表的屬性有沖突  

 *    解決的方案:去掉關聯表中外鍵對應的屬性

 

@Column(name="stu_id")

private Long stuId;

 

public Long getStuId() {

return stuId;

}

 

public void setStuId(Long stuId) {

this.stuId = stuId;

}

*/

 

/**

 * 1、分數和學生信息是多對一的關系

 * 2、只需要一個學生的實體來引用學生的信息

 */

@ManyToOne

@JoinColumn(name="stu_id")

private Student student;

 

public Student getStudent() {

return student;

}

 

public void setStudent(Student student) {

this.student = student;

}

 

5.4 一對一實現

5.4.1 說明

需求:通過ID查詢學生的信息,通過也獲得學生對應的學生身份信息。

 

 

 

 

5.4.2 配置步驟

5.4.2.1 第一步:創建項目

復制一對多的示例項目即可。

 

5.4.2.2 第二步:創建單表實體類

1)創建Student

 

2)創建Identity

package cn.zj.jpa.entity;

 

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.Table;

 

@Entity

@Table(name="tb_identity")

public class Identity {

 

@Id

/*由於一對一,外鍵表的主鍵字段值來自於主鍵表,所以只能手工輸入 

手工輸入ID值,可以不指定主鍵生成策略 */

// @GeneratedValue   

@Column(name="stu_id")

private Long stuId;

 

@Column(name="stu_identity")

private String stuIdentity;

 

@Column(name="stu_no")

private String stuNo;

@OneToOne

//2.必須要指定關聯的外鍵

@JoinColumn(name="stu_id")

private Student student;

public Identity() {

super();

}

    // 補全get、set方法

}

 

5.4.2.3 第三步配置一對一關聯關系

說明:一對一關聯關系,也是支持雙向配置的。

可以在Student類、Identity類中同時配置關聯關系。

 

1)修改Student類,配置一對一關系。

//學生表與學生身份表是一對一的關系,意味着,一個學生只能對應一條學生身份信息

//所以使用引用

//1.聲明關系,一對一

@OneToOne 

//2.必須要指定關聯的外鍵

@JoinColumn(name="stu_id")

private Identity identity;

  

public Identity getIdentity() {

return identity;

}

public void setiIdentity(Identity identity) {

this.identity = identity;

}

 

2)修改Score

//1.聲明關系,一對一 

@OneToOne 

//2.指定關聯的外鍵 

@JoinColumn(name="stu_id") 

private Student student; 

public Student getStudent() { 

return student; 

public void setStudent(Student student) { 

this.student = student; 

 

5.4.2.4 第四步:測試

說明:可以分別測試方向一對一關系。

@Test

public void testOne2One1(){

//1.獲得實體管理類

EntityManager manager = JPAUtils.getEntityManger();

 

Student student = manager.find(Student.class, 1L);

System.out.println("學生id:"+student.getStuId()+",學生姓名:"+student.getStuName());

Identity identity = student.getIdentity();

System.out.println("學生學號:"+identity.getStuNo()+",身份證號:"+identity.getStuIdentity());

 

//6、關閉資源

manager.close();

}

 

@Test

public void testOne2One2(){

//1.獲得實體管理類

EntityManager manager = JPAUtils.getEntityManger();

Identity identity = manager.find(Identity.class, 1L);

System.out.println("學生學號:"+identity.getStuNo()+",身份證號:"+identity.getStuIdentity());

Student student = identity.getStudent();

System.out.println("學生id:"+student.getStuId()+",學生姓名:"+student.getStuName());

//6、關閉資源

manager.close();

}

 

1)測試學生關聯身份信息

測試結果:

 

 

 

2)測試身份信息關聯學生。

 

 

 

一對一配置成功!!!

5.5 配置多對多

5.5.1 說明

需求: 

1通過ID查詢學生的信息,通過該學生信息也獲得對應的教師信息。 

2通過ID查詢教師的信息,通過教師信息也獲得該對應的學生信息。 

  

如圖所示:一個學生可以有多個教師,一個教師也可以有多個學生,所以學生和教師的關系是多對多的關系。 

  

 

 

  

如上圖所示: 

如果要從學生表的信息獲得教師表的信息。必須需要三個條件 

1. 必須需要有一個中間表 

2. 必須需要中間表對應本表的外鍵 

3. 必須需要中間表對應關聯表的外鍵 

 

5.5.2 配置步驟

5.5.2.1 第一步:創建項目

復制一個示例項目即可。

 

5.5.2.2 第二步:創建單表實體類

學生實體類Student

//1.指定實體類與表名的關系

//@Entity注解,指定該實體類是一個基於JPA規范的實體類

@Entity 

//@Table注解,指定當前實體類關聯的表

@Table(name="tb_student")

public class Student {

//@Id注解:聲明屬性為一個OID屬性

@Id 

//@GeneratedValue注解,指定主鍵生成策略

@GeneratedValue(strategy=GenerationType.IDENTITY)

//@Column注解,設置屬性與數據庫字段的關系,如果屬性名和表的字段名相同,可以不設置

@Column(name="stu_id")

private Long stuId;//BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '學生編號',

@Column(name="stu_name")

private String stuName;//VARCHAR(50) NULL DEFAULT NULL COMMENT '學生名字',

@Column(name="stu_age")

private Integer stuAge;//INT(11) NULL DEFAULT NULL COMMENT '學生年齡',

@Column(name="stu_password")

private String stuPassword;//VARCHAR(50) NULL DEFAULT NULL COMMENT '登錄密碼',

   

public Student() {

super();

}

//補全get、set方法

}

 

教師實體類Teacher

@Entity

@Table(name="tb_teacher")

public class Teacher {

 

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

@Column(name="tea_id")

private Long teaId;

 

@Column(name="tea_name")

private String teaName;

 

@Column(name="tea_password")

private String teaPassword;

 

public Teacher() {

super();

}

//補全getset方法

}

 

5.5.2.3 第三步:配置多對多關系

1)學生關聯教師,修改Student

// 學生表和教師表是多對多的關系

// 所以,一個學生可以有多個教師,所以需要使用集合來存儲教師信息

//1.聲明關系,多對多

@ManyToMany 

//2.設置關聯的條件

//JoinTable用於對應中間表的設置     joinColumns設置中間表與本表關聯的外鍵    inverseJoinColumns設置中間表與關聯表對應的外鍵

@JoinTable(name="tb_stu_tea" ,joinColumns=@JoinColumn(name="stu_id"),inverseJoinColumns=@JoinColumn(name="tea_id"))

private List<Teacher> teachers;

  

public List<Teacher> getTeachers() {

return teachers;

}

  

public void setTeachers(List<Teacher> teachers) {

this.teachers = teachers;

}

 

2)教師關聯學生,修改Teacher

//因為教師與學生是多對多的關系,所以一個教師也可以有多個學生,需要使用集合來存儲學生的數據

//1.聲明教師和學生的關系,多對多

@ManyToMany 

//2.設置關聯的條件

@JoinTable(name="tb_stu_tea" ,joinColumns=@JoinColumn(name="tea_id"),inverseJoinColumns=@JoinColumn(name="stu_id"))

private List<Student> students;

  

public List<Student> getStudents() {

return students;

}

  

public void setStudents(List<Student> students) {

this.students = students;

}  

 

5.5.2.4 測試

5.5.2.4.1 Step1:測試學生關聯教師

測試代碼

@Test

public void testMany2Many1(){

 

//1.獲得實體管理類

EntityManager manager = JPAUtils.getEntityManger();

 

Student student = manager.find(Student.class, 1L);

System.out.println("學生id:"+student.getStuId()+",學生姓名:"+student.getStuName());

 

List<Teacher> teachers = student.getTeachers();

for (Teacher teacher : teachers) {

System.out.println("教師id:"+teacher.getTeaId()+",教師姓名:"+teacher.getTeaName());

}

//2、關閉資源

manager.close();

}

 

測試結果:

 

 

 

 

5.5.2.4.2 Step2:測試教師關聯學生

測試代碼

@Test

public void testMany2Many2(){

 

//1.獲得實體管理類

EntityManager manager = JPAUtils.getEntityManger();

 

Teacher teacher = manager.find(Teacher.class, 1L);

System.out.println("教師id:"+teacher.getTeaId()+",教師姓名:"+teacher.getTeaName());

 

List<Student> students = teacher.getStudents();

for (Student student : students) {

System.out.println("學生id:"+student.getStuId()+",學生姓名:"+student.getStuName());

}

//2、關閉資源

manager.close();

}

 

 

 

測試結果:

 

 

 

多對多配置成功!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM