Technologieaustausch

[Spring Boot] Beziehungszuordnungsentwicklung (3): Viele-zu-viele-Zuordnung

2024-07-12

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

JPA vom Einstieg bis zur BefähigungDie Serie 》 umfasst die folgenden Artikel:


existieren viel zu viel Im Assoziationsverhältnis nur durchZwischentisch Eine Zuordnung kann nicht durch das Hinzufügen von Fremdschlüsseln erreicht werden.

Anmerkung @Viel zu viel Wird für den Sender und Empfänger der Beziehung verwendet. Das sendende Ende der Beziehung definiert die Feldattribute des empfangenden Endes eines Sammlungstyps, und das empfangende Ende der Beziehung muss keine Definitionen vornehmen.

1. Entitäten erstellen

1.1 Erstellen Sie eine Student-Entität

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 Erstellen Sie eine Teacher-Entität

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

existieren viel zu viel Hier sind einige Dinge, die Sie in Ihrer Beziehung beachten sollten:

  • Beide Partner der Beziehung können als Herren fungieren.
  • existieren joinColumns von@JoinColumn(name="t_id") Mitte,t_id Ist der Fremdschlüssel in JoinTable.Da die Primärschlüssel von Schüler und Lehrer beide sindid, daher wird es hier weggelassen referencedColumnName="id"
  • Beim Entwerfen der Kaskadenbeziehung zwischen Modellen muss berücksichtigt werden, welche Kaskadenregeln verwendet werden sollen.
  • Wenn festgelegt cascade = CascadeType.PERSIST, dann ausführen save wird wann aufgerufenonPersist() Methode.Diese Methode ruft rekursiv die äußere Klasse (Schüler oder Lehrer) auf.onPersist() Führen Sie eine Kaskadenaddition durch.Da der Mehrwert jedoch hinzugefügt wurde, wird er gemeldetdetached entity passed to persist Fehler, Kaskadenvorgang abbrechen (entfernen).cascade = CascadeType.PERSIST).

Fügen Sie hier eine Bildbeschreibung ein

2. Erstellen Sie Tests

Die Service- und Repository-Ebenen befinden sich in „Entwicklung der Beziehungszuordnung (1): Eins-zu-Eins-Zuordnung„Wie bereits erwähnt, gibt es hier keinen Unterschied, daher werde ich nicht auf Details eingehen und direkt zum Code-Schreiben der Testschicht übergehen.“

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

Führen Sie die Testklasse ausReglerFolgende Ergebnisse werden ausgegeben:

Fügen Sie hier eine Bildbeschreibung ein

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein

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