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.com
* @description:单向
*/
@Entity
@Table(name = "t_student")
public class Student {
@Id
@GeneratedValue
private 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;
} @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.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");
} // t1老师教2个学生s1,s2
// t2老师教3个学生s1,s2,s3
// 总共10条insert
@Test
public 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,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 = 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().commit();
} // 删除t1的教的所有学生
@Test
public void delete() throws Exception {
persist(); entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin(); Teacher t1 = entityManager.find(Teacher.class, 1L);
t1.getStudents().clear(); entityManager.getTransaction().commit();
} @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

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



JPA 系列教程6-单向多对多的更多相关文章

  1. JPA 系列教程7-双向多对多

    双向多对多的ddl语句 同单向多对多表的ddl语句一致 Student package com.jege.jpa.many2many; import java.util.HashSet; import ...

  2. JPA 系列教程3-单向多对一

    JPA中的@ManyToOne 主要属性 - name(必需): 设定"many"方所包含的"one"方所对应的持久化类的属性名 - column(可选): 设 ...

  3. JPA 系列教程4-单向一对多

    JPA中的@OneToMany @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OneToMany { Class tar ...

  4. JPA 系列教程5-双向一对多

    双向一对多的ddl语句 同单向多对一,单向一对多表的ddl语句一致 Product package com.jege.jpa.one2many; import javax.persistence.En ...

  5. JPA 系列教程21-JPA2.0-@MapKeyColumn

    @MapKeyColumn 用@JoinColumn注解和@MapKeyColumn处理一对多关系 ddl语句 CREATE TABLE `t_employee` ( `id` bigint(20) ...

  6. JPA 系列教程17-继承-独立表-TABLE_PER_CLASS

    PerTable策略 每个具体的类一个表的策略 举例 这种映射策略每个类都会映射成一个单独的表,类的所有属性,包括继承的属性都会映射成表的列. 这种映射策略的缺点是:对多态关系的支持有限,当查询涉及到 ...

  7. JPA 系列教程16-继承-联合子类-JOINED

    联合子类策略 这种情况下子类的字段被映射到各自的表中,这些字段包括父类中的字段,并执行一个join操作来实例化子类. 举例 如果实体类Teacher继承实体类Person,实体类Student也继承自 ...

  8. JPA 系列教程13-复合主键-@EmbeddedId+@Embeddable

    复合主键 指多个主键联合形成一个主键组合 需求产生 比如航线一般是由出发地及目的地确定,如果要确定唯一的航线就可以用出发地和目的地一起来表示 ddl语句 同复合主键-2个@Id和复合主键-2个@Id+ ...

  9. JPA 系列教程12-复合主键-2个@Id+@IdClass

    复合主键 指多个主键联合形成一个主键组合 需求产生 比如航线一般是由出发地及目的地确定,如果要确定唯一的航线就可以用出发地和目的地一起来表示 ddl语句 同复合主键-2个@Id一样 Airline p ...

随机推荐

  1. geom设置—折线图

    折线图在R中也是很常见的一种图形,相对而言也比较简单. geom_line(mapping = NULL, data = NULL, stat = "identity", posi ...

  2. SSH 两个表全套增删改(运动员住宿管理)

    0.创建如下oracle的命令 create table HOTALINFO ( HOTALID ) not null, HOTALNAME ) not null, HOTALADDRESS ) no ...

  3. 三、ASP.NET MVC Controller 控制器(二:IController控制器的创建过程)

    阅读目录: 1.开篇介绍 2.ASP.NETMVC IControllerFactory 控制器工厂接口 3.ASP.NETMVC DefaultControllerFactory 默认控制器工厂 4 ...

  4. thrift安装笔记

    Thrift源于大名鼎鼎的facebook之手,在2007年facebook提交Apache基金会将Thrift作为一个开源项目,对于当时 的facebook来说创造thrift是为了解决facebo ...

  5. POCO系列之——延迟加载

    当我们进行查询的时候,哪些关系的数据将会被加载到内存呢?所有相关的对象都需要吗?在一些场合可能有意义,例如,当查询的实体仅仅拥有一个相关的子实体,但是,多数情况下,你可能只需要加载部分数据,或者你喜欢 ...

  6. LeetCode OJ 152. Maximum Product Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  7. Multidimensional Arrays

    Overview An array having more than two dimensions is called a multidimensional array in the MATLAB® ...

  8. Quartz 2D中的基本图形绘制

    在iOS中绘图一般分为以下几个步骤: 1.获取绘图上下文 2.创建并设置路径 3.将路径添加到上下文 4.设置上下文状态 5.绘制路径 6.释放路径 在UIKit中默认已经为我们准备好了一个图形上下文 ...

  9. Java 基于log4j的日志工具类

    对log4j日志类进行了简单封装,使用该封装类的优势在于以下两点: 1.不必在每个类中去创建对象,直接类名 + 方法即可 2.可以很方便的打印出堆栈信息 package com.tradeplatfo ...

  10. jQuery(1)——了解jQuery

    jQuery 终于开始了jQuery的学习了,好开心,虽然感觉JavaScript并没有学好,尴尬.木事,咋们慢慢来.fighting [jQuery简介] jQuery是继Prototype之后又一 ...