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. yii中数据模型的使用

    模型是 CModel 或其子类的实例.模型用于保持数据以及与其相关的业务逻辑. 模型是单独的数据对象.它可以是数据表中的一行,或者一个用户输入的表单. yii数据库操作使用的是PDO,所以使用yii的 ...

  2. libmad编译

    patch -Np1 -i ../libmad-0.15.1b-fixes-1.patch && sed "s@AM_CONFIG_HEADER@AC_CONFIG_HEAD ...

  3. 对Big O的新的认识

    对Big O的新的认识 一个问题,它有很多种算法都能实现.每种算法它的时间.空间复杂度不一样.比如: 问题1: 求最大连续子序列和的问题,可以有O(n3).O(n2).O(nlogn)和O(n)四种时 ...

  4. apicloud 初学

    html5:在创建html时为了防止页面缩放等不兼容效果,要创建个viewport <meta name="viewport" content="maximum-s ...

  5. CentOS修复“OpenSSL Heartbleed漏洞”方法

    转载 http://www.coolhots.net/article/229.shtml

  6. php练习1

    <?php$conn=mysqli_init();if(!conn){ echo "mysqli_init error"; exit(0);}$ret=mysqli_real ...

  7. mongoDB6--查询表达式

    接上一篇总结<深入查询表达式1>上一篇我们介绍了mongodb的一些表达式的深入应用.可能大家觉得有些指令比较难记,下面给大家介绍一些简洁的表达式.给大家介绍的是以下两个指令:分别是$wh ...

  8. JSP之JavaBean

    一.定义 1 JavaBean是一个遵循特定写法的Java类,它通常具有如下特点: 这个Java类必须具有一个无参的构造函数 属性必须私有化. 私有化的属性必须通过public类型的方法暴露给其它程序 ...

  9. android Handler vs Timer

    Handler vs Timer 在我们Android开发过程中,经常需要执行一些短周期的定时任务,这时候有两个选择Timer或者Handler.然而个人认为: Handler 在多个方面比Timer ...

  10. Hbase查看

    Client HBase Client使用HBase的RPC机制与HMaster和HRegionServer进行通信,对于管理类操作,Client与HMaster进行RPC:对于数据读写类操作,Cli ...