Berbagi teknologi

[Spring Boot] Pengembangan pemetaan hubungan (3): pemetaan banyak ke banyak

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

JPA dari awal hingga kemahiran》 seri mencakup artikel berikut:


Pengembangan pemetaan hubungan (3): pemetaan banyak ke banyak

ada banyak ke banyak Dalam hubungan pergaulan hanya melaluitabel perantara Pemetaan tidak dapat dicapai dengan menambahkan kunci asing.

anotasi @Banyak ke banyak Digunakan untuk pengirim dan penerima hubungan. Ujung hubungan yang mengirim mendefinisikan atribut bidang dari ujung penerima dari suatu tipe koleksi, dan ujung penerima hubungan tidak perlu membuat definisi apa pun.

1. Buat entitas

1.1 Buat entitas Siswa

package com.example.demo.entity;

import lombok.Data;

import javax.persistence.*;
import java.util.List;
import java.util.Set;

@Entity
@Data
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String name;
    @Column(columnDefinition = "enum('male','female')")
    private String sex;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "teacher_student", joinColumns = {@JoinColumn(name = "s_id")}, inverseJoinColumns = {@JoinColumn(name = "t_id")})
    private Set<Teacher> teachers;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

1.2 Buat entitas Guru

package com.example.demo.entity;

import lombok.Data;

import javax.persistence.*;
import java.util.List;
import java.util.Set;

@Data
@Entity
public class Teacher {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    private String name;
    @ManyToMany(fetch = FetchType.LAZY)
    /**
     * Description:
     * 1、关系两边都作为主控;
     * 2、joinColumns 中 @JoinColumn(name="t_id") 其中 t_id 为 JoinTable 中的外键,由于 Student 和 Teacher 的主键都为 id 这边就省略 referencedColumnName="id"。
     */
    @JoinTable(name = "teacher_student", joinColumns = {@JoinColumn(name = "t_id")}, inverseJoinColumns = {@JoinColumn(name = "s_id")})
    private Set<Student> students;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

ada banyak ke banyak Berikut beberapa hal yang perlu diperhatikan dalam hubungan Anda:

  • Kedua pihak dalam hubungan bisa berperan sebagai tuan.
  • ada joinColumns dari@JoinColumn(name="t_id") tengah,t_id Apakah kunci asing di JoinTable.Karena kunci utama Siswa dan Guru keduanyaid, jadi dihilangkan di sini referencedColumnName="id"
  • Saat merancang hubungan kaskade antar model, perlu mempertimbangkan aturan kaskade apa yang harus digunakan.
  • Jika diatur cascade = CascadeType.PERSIST, lalu mengeksekusi save akan dipanggil kapanonPersist() metode.Metode ini akan memanggil kelas luar (Siswa atau Guru) secara rekursif.onPersist() Lakukan penambahan kaskade.Tapi karena sudah ada nilai tambah maka akan dilaporkandetached entity passed to persist Kesalahan, batalkan operasi kaskade (hapuscascade = CascadeType.PERSIST).

Masukkan deskripsi gambar di sini

2. Buat tes

Lapisan Layanan dan Repositori ada di "Pengembangan pemetaan hubungan (1): pemetaan satu-ke-satu》Sudah disebutkan, tidak ada perbedaan di sini, jadi saya tidak akan membahas detailnya dan langsung ke penulisan kode pada lapisan pengujian.

package com.example.demo.entity;

import com.example.demo.repository.StudentRepository;
import com.example.demo.repository.TeacherRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.HashSet;
import java.util.Set;

import static org.junit.Assert.*;

@SpringBootTest
@RunWith(SpringRunner.class)
public class ManyToManyTest {
    @Autowired
    private StudentRepository studentRepository;
    @Autowired
    private TeacherRepository teacherRepository;

    @Test
    public void add() {

        Set<Teacher> teachers = new HashSet<>();
        Set<Student> students = new HashSet<>();

        Student student1 = new Student();
        student1.setName("张三");
        students.add(student1);
        studentRepository.save(student1);

        Student student2 = new Student();
        student2.setName("李四");
        students.add(student2);
        studentRepository.save(student2);

        Teacher teacher1 = new Teacher();
        teacher1.setName("皮皮老师");
        teacher1.setStudents(students);
        teachers.add(teacher1);
        teacherRepository.save(teacher1);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

Jalankan kelas tes dipengontrolHasil berikut adalah keluarannya:

Masukkan deskripsi gambar di sini

Masukkan deskripsi gambar di sini
Masukkan deskripsi gambar di sini
Masukkan deskripsi gambar di sini
Masukkan deskripsi gambar di sini
Masukkan deskripsi gambar di sini

🚀 对于双向 ManyToMany 关系,注解 @ManyToMany 用于关系的发出端和接收端。另外,关系的接收端需要设置 @ManyToMany(mappedBy='集合类型发出端实体的字段名称')