Partage de technologie

[Spring Boot] Développement de cartographie relationnelle (3) : cartographie plusieurs-à-plusieurs

2024-07-12

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

JPA de l'entrée à la compétence》 La série comprend les articles suivants :


Développement de cartographie relationnelle (3) : cartographie plusieurs-à-plusieurs

exister plusieurs à plusieurs Dans la relation d'association, uniquement à traverstable intermédiaire Le mappage ne peut pas être réalisé en ajoutant des clés étrangères.

annotation @Plusieurs à plusieurs Utilisé pour l'expéditeur et le destinataire de la relation. L'extrémité émettrice de la relation définit les attributs de champ de l'extrémité réceptrice d'un type de collection, et l'extrémité réceptrice de la relation n'a pas besoin de faire de définitions.

1. Créer des entités

1.1 Créer une entité étudiante

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 Créer une entité Enseignant

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

exister plusieurs à plusieurs Voici quelques éléments à noter dans votre relation :

  • Les deux parties à la relation peuvent jouer le rôle de maîtres.
  • exister joinColumns de@JoinColumn(name="t_id") milieu,t_id Est la clé étrangère dans JoinTable.Puisque les clés primaires de Student et Teacher sont toutes deuxid, donc il est omis ici referencedColumnName="id"
  • Lors de la conception de la relation en cascade entre les modèles, il est nécessaire de réfléchir aux règles de cascade à utiliser.
  • Si défini cascade = CascadeType.PERSIST, puis en exécutant save sera appelé quandonPersist() méthode.Cette méthode appellera récursivement la classe externe (Étudiant ou Enseignant)onPersist() Effectuez un ajout en cascade.Mais comme la valeur a été ajoutée, elle sera signaléedetached entity passed to persist Erreur, annuler l'opération en cascade (supprimercascade = CascadeType.PERSIST).

Insérer la description de l'image ici

2. Créer des tests

Les couches Service et Repository sont dans "Développement de cartographie relationnelle (1) : cartographie individuelle》Déjà mentionné, il n'y a pas de différence ici, je n'entrerai donc pas dans les détails et passerai directement à l'écriture du code de la couche de test.

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

Exécutez la classe de test dansmanetteLes résultats suivants sont générés :

Insérer la description de l'image ici

Insérer la description de l'image ici
Insérer la description de l'image ici
Insérer la description de l'image ici
Insérer la description de l'image ici
Insérer la description de l'image ici

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