JPA 系列教程6

JPA中的@ManyToMany

@ManyToMany注释表示模型类是多对多关系的一端。
@JoinTable 描述了多对多关系的数据表关系。
  • name 属性指定中间表名称
  • joinColumns 定义中间表与Teacher 表的外键关系
  • inverseJoinColumns属性定义了中间表与另外一端(Student)的外键关系

单向多对多表的ddl语句

CREATE TABLE `t_student` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`sname` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;CREATE TABLE `t_teacher` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`tname` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;CREATE TABLE `t_teacher_student` (`teacher_id` bigint(20) NOT NULL,`student_id` bigint(20) NOT NULL,PRIMARY KEY (`teacher_id`,`student_id`),KEY `FK_o82lxg0wi1y88lit4fy7lkg7t` (`student_id`),CONSTRAINT `FK_1epgkih044inndyv1dtihcb7r` FOREIGN KEY (`teacher_id`) REFERENCES `t_teacher` (`id`),CONSTRAINT `FK_o82lxg0wi1y88lit4fy7lkg7t` FOREIGN KEY (`student_id`) REFERENCES `t_student` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Student

package com.jege.jpa.many2many;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;/*** @author JE哥* @email 1272434821@qq* @description:单向*/
@Entity
@Table(name = "t_student")
public class Student {@Id@GeneratedValueprivate Long id;private String sname;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;}@Overridepublic 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* @description:单向:一个老师教多个学生*/
@Entity
@Table(name = "t_teacher")
public class Teacher {@Id@GeneratedValueprivate 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;}@Overridepublic 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.BeforeClass;
import org.junit.Test;/*** @author JE哥* @email 1272434821@qq* @description:单向多对多Test*/
public class Many2ManyTest {private static EntityManagerFactory entityManagerFactory = null;private EntityManager entityManager = null;@BeforeClasspublic static void setUpBeforeClass() throws Exception {entityManagerFactory = Persistence.createEntityManagerFactory("com.jege.jpa");}// t1老师教2个学生s1,s2// t2老师教3个学生s1,s2,s3// 总共10条insert@Testpublic void persist() throws Exception {entityManager = entityManagerFactory.createEntityManager();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,s3t1.getStudents().add(s1);t1.getStudents().add(s2);t2.getStudents().add(s1);t2.getStudents().add(s2);t2.getStudents().add(s3);entityManager.getTransaction()mit();// 发出5条insert中间表entityManager.close();}// t1老师教2个学生s1,s2// 修改为 教2个学生s1,s3:先删除在添加@Testpublic void update() throws Exception {persist();entityManager = entityManagerFactory.createEntityManager();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()mit();}// 删除t1的教的所有学生@Testpublic void delete() throws Exception {persist();entityManager = entityManagerFactory.createEntityManager();entityManager.getTransaction().begin();Teacher t1 = entityManager.find(Teacher.class, 1L);t1.getStudents().clear();entityManager.getTransaction()mit();}@Afterpublic void tearDown() throws Exception {if (entityManager != null && entityManager.isOpen())entityManager.close();}@AfterClasspublic static void tearDownAfterClass() throws Exception {if (entityManagerFactory != null && entityManagerFactory.isOpen())entityManagerFactory.close();}
}

源码地址

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

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>

JPA 系列教程6

JPA中的@ManyToMany

@ManyToMany注释表示模型类是多对多关系的一端。
@JoinTable 描述了多对多关系的数据表关系。
  • name 属性指定中间表名称
  • joinColumns 定义中间表与Teacher 表的外键关系
  • inverseJoinColumns属性定义了中间表与另外一端(Student)的外键关系

单向多对多表的ddl语句

CREATE TABLE `t_student` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`sname` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;CREATE TABLE `t_teacher` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`tname` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;CREATE TABLE `t_teacher_student` (`teacher_id` bigint(20) NOT NULL,`student_id` bigint(20) NOT NULL,PRIMARY KEY (`teacher_id`,`student_id`),KEY `FK_o82lxg0wi1y88lit4fy7lkg7t` (`student_id`),CONSTRAINT `FK_1epgkih044inndyv1dtihcb7r` FOREIGN KEY (`teacher_id`) REFERENCES `t_teacher` (`id`),CONSTRAINT `FK_o82lxg0wi1y88lit4fy7lkg7t` FOREIGN KEY (`student_id`) REFERENCES `t_student` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Student

package com.jege.jpa.many2many;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;/*** @author JE哥* @email 1272434821@qq* @description:单向*/
@Entity
@Table(name = "t_student")
public class Student {@Id@GeneratedValueprivate Long id;private String sname;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;}@Overridepublic 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* @description:单向:一个老师教多个学生*/
@Entity
@Table(name = "t_teacher")
public class Teacher {@Id@GeneratedValueprivate 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;}@Overridepublic 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.BeforeClass;
import org.junit.Test;/*** @author JE哥* @email 1272434821@qq* @description:单向多对多Test*/
public class Many2ManyTest {private static EntityManagerFactory entityManagerFactory = null;private EntityManager entityManager = null;@BeforeClasspublic static void setUpBeforeClass() throws Exception {entityManagerFactory = Persistence.createEntityManagerFactory("com.jege.jpa");}// t1老师教2个学生s1,s2// t2老师教3个学生s1,s2,s3// 总共10条insert@Testpublic void persist() throws Exception {entityManager = entityManagerFactory.createEntityManager();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,s3t1.getStudents().add(s1);t1.getStudents().add(s2);t2.getStudents().add(s1);t2.getStudents().add(s2);t2.getStudents().add(s3);entityManager.getTransaction()mit();// 发出5条insert中间表entityManager.close();}// t1老师教2个学生s1,s2// 修改为 教2个学生s1,s3:先删除在添加@Testpublic void update() throws Exception {persist();entityManager = entityManagerFactory.createEntityManager();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()mit();}// 删除t1的教的所有学生@Testpublic void delete() throws Exception {persist();entityManager = entityManagerFactory.createEntityManager();entityManager.getTransaction().begin();Teacher t1 = entityManager.find(Teacher.class, 1L);t1.getStudents().clear();entityManager.getTransaction()mit();}@Afterpublic void tearDown() throws Exception {if (entityManager != null && entityManager.isOpen())entityManager.close();}@AfterClasspublic static void tearDownAfterClass() throws Exception {if (entityManagerFactory != null && entityManagerFactory.isOpen())entityManagerFactory.close();}
}

源码地址

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

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>