• JPA 系列教程7-双向多对多


    双向多对多的ddl语句

    同单向多对多表的ddl语句一致

    Student

    package com.jege.jpa.many2many;
    
    import java.util.HashSet;
    import java.util.Set;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.ManyToMany;
    import javax.persistence.Table;
    
    /**
     * @author JE哥
     * @email 1272434821@qq.com
     * @description:双向:关系被维护端:不能操作中间表
     */
    @Entity
    @Table(name = "t_student")
    public class Student {
      @Id
      @GeneratedValue
      private Long id;
      private String sname;
      @ManyToMany(mappedBy = "students")
      private Set<Teacher> teachers = new HashSet<Teacher>();
    
      public Student() {
    
      }
    
      public Student(String sname) {
        this.sname = sname;
      }
    
      public Long getId() {
        return id;
      }
    
      public void setId(Long id) {
        this.id = id;
      }
    
      public String getSname() {
        return sname;
      }
    
      public void setSname(String sname) {
        this.sname = sname;
      }
    
      public Set<Teacher> getTeachers() {
        return teachers;
      }
    
      public void setTeachers(Set<Teacher> teachers) {
        this.teachers = teachers;
      }
    
      @Override
      public String toString() {
        return "Student [id=" + id + ", sname=" + sname + "]";
      }
    
    }
    

    Teacher

    package com.jege.jpa.many2many;
    
    import java.util.HashSet;
    import java.util.Set;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.JoinTable;
    import javax.persistence.ManyToMany;
    import javax.persistence.Table;
    
    /**
     * @author JE哥
     * @email 1272434821@qq.com
     * @description:双向:关系维护端:可以操作中间表
     */
    @Entity
    @Table(name = "t_teacher")
    public class Teacher {
      @Id
      @GeneratedValue
      private Long id;
      private String tname;
      // @ManyToMany注释表示Teacher是多对多关系的一端。
      // @JoinTable描述了多对多关系的数据表关系。name属性指定中间表名称,joinColumns定义中间表与Teacher表的外键关系。
      // 中间表Teacher_Student的Teacher_ID列是Teacher表的主键列对应的外键列,inverseJoinColumns属性定义了中间表与另外一端(Student)的外键关系。
      @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
      @JoinTable(name = "t_teacher_student", joinColumns = { @JoinColumn(name = "teacher_id") }, inverseJoinColumns = {
          @JoinColumn(name = "student_id") })
      private Set<Student> students = new HashSet<Student>();
    
      public Teacher() {
    
      }
    
      public Teacher(String tname) {
        this.tname = tname;
      }
    
      public Long getId() {
        return id;
      }
    
      public void setId(Long id) {
        this.id = id;
      }
    
      public String getTname() {
        return tname;
      }
    
      public void setTname(String tname) {
        this.tname = tname;
      }
    
      public Set<Student> getStudents() {
        return students;
      }
    
      public void setStudents(Set<Student> students) {
        this.students = students;
      }
    
      @Override
      public String toString() {
        return "Teacher [id=" + id + ", tname=" + tname + "]";
      }
    }

    Many2ManyTest

    package com.jege.jpa.many2many;
    
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Persistence;
    
    import org.junit.After;
    import org.junit.AfterClass;
    import org.junit.Before;
    import org.junit.BeforeClass;
    import org.junit.Test;
    
    /**
     * @author JE哥
     * @email 1272434821@qq.com
     * @description:双向多对多Test
     */
    public class Many2ManyTest {
      private static EntityManagerFactory entityManagerFactory = null;
      private EntityManager entityManager = null;
    
      @BeforeClass
      public static void setUpBeforeClass() throws Exception {
        entityManagerFactory = Persistence.createEntityManagerFactory("com.jege.jpa");
      }
    
      @Before
      public void setUp() throws Exception {
        entityManager = entityManagerFactory.createEntityManager();
      }
    
      // t1老师教2个学生s1,s2
      // t2老师教3个学生s1,s2,s3
      // 总共10条insert
      @Test
      public void persist() throws Exception {
        entityManager.getTransaction().begin();
    
        Teacher t1 = new Teacher("t1");
        Teacher t2 = new Teacher("t2");
    
        Student s1 = new Student("s1");
        Student s2 = new Student("s2");
        Student s3 = new Student("s3");
    
        entityManager.persist(t1);
        entityManager.persist(t2);
    
        entityManager.persist(s1);
        entityManager.persist(s2);
        entityManager.persist(s3);// 全部发出5条insert单表
    
        // 添加中间表
        // t1老师教2个学生s1,s2
        // t2老师教3个学生s1,s2,s3
        t1.getStudents().add(s1);
        t1.getStudents().add(s2);
    
        t2.getStudents().add(s1);
        t2.getStudents().add(s2);
        t2.getStudents().add(s3);
    
        entityManager.getTransaction().commit();// 发出5条insert中间表
        entityManager.close();
      }
    
      // t1老师教2个学生s1,s2
      // 修改为 教2个学生s1,s3:先删除在添加
      @Test
      public void update() throws Exception {
        persist();
    
        entityManager.getTransaction().begin();
    
        Teacher t1 = entityManager.find(Teacher.class, 1L);
        Student s2 = entityManager.find(Student.class, 2L);
        Student s3 = entityManager.find(Student.class, 3L);
        // 删除
        t1.getStudents().remove(s2);
        // 添加
        t1.getStudents().add(s3);
    
        entityManager.getTransaction().commit();
      }
    
      // 删除t1的教的所有学生
      @Test
      public void delete() throws Exception {
        persist();
    
        entityManager.getTransaction().begin();
    
        Teacher t1 = entityManager.find(Teacher.class, 1L);
        t1.getStudents().clear();
    
        entityManager.getTransaction().commit();
      }
    
      // insert 3条,单表插入,中间表无反应
      // 因为Student是关系被维护端:不能操作中间表
      @Test
      public void persist2() throws Exception {
        Teacher teacher = new Teacher("t1");
    
        Student student1 = new Student("s1");
        Student student2 = new Student("s2");
    
        student1.getTeachers().add(teacher);// 插入中间表
        student2.getTeachers().add(teacher);
    
        entityManager.getTransaction().begin();
        entityManager.persist(teacher);
        entityManager.persist(student1);
        entityManager.persist(student2);
        entityManager.getTransaction().commit();
      }
    
      @Test
      public void find() throws Exception {
        persist();
    
        entityManager = entityManagerFactory.createEntityManager();
        Teacher teacher = entityManager.find(Teacher.class, 1L);
        System.out.println(teacher.getTname());
        System.out.println("------------------");
        System.out.println(teacher.getStudents());
    
      }
    
      @Test
      public void find2() throws Exception {
        persist();
    
        entityManager = entityManagerFactory.createEntityManager();
        Student student = entityManager.find(Student.class, 1L);
        System.out.println(student.getSname());
        System.out.println("------------------");
        System.out.println(student.getTeachers());
    
      }
    
      @After
      public void tearDown() throws Exception {
        if (entityManager != null && entityManager.isOpen())
          entityManager.close();
      }
    
      @AfterClass
      public static void tearDownAfterClass() throws Exception {
        if (entityManagerFactory != null && entityManagerFactory.isOpen())
          entityManagerFactory.close();
      }
    }

    其他关联项目

    源码地址

    https://github.com/je-ge/jpa

    如果觉得我的文章对您有帮助,请打赏支持。您的支持将鼓励我继续创作!谢谢!
    微信打赏
    支付宝打赏

  • 相关阅读:
    微信机器人11python自制微信机器人,定时发送天气预报
    微信机器人10Python创建微信机器人
    微信小程序如何调用后台service(图文教程)
    python爬虫:使用Selenium模拟浏览器行为
    Python模拟浏览器发送http请求
    TextClip的list和search方法报错:UnicodeDecodeError: utf-8 codec canot decode byte 0xb7 in position 8
    TextClip构造方法报OSError:MoviePy creation of None failed because of the following [WinError 2]系统找不到指定的文件
    moviepy音视频剪辑:视频基类VideoClip子类DataVideoClip、UpdatedVideoClip、ImageClip、ColorClip、TextClip类详解
    moviepy音视频剪辑:视频基类VideoClip子类DataVideoClip、UpdatedVideoClip、ImageClip、ColorClip、TextClip及使用案例
    moviepy音视频剪辑:mask clip遮罩剪辑、遮片、蒙版的作用以及其包含的构成内容
  • 原文地址:https://www.cnblogs.com/je-ge/p/6180876.html
Copyright © 2020-2023  润新知