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.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();
}
}
源码地址
如果觉得我的文章对您有帮助,请打赏支持。您的支持将鼓励我继续创作!谢谢!
JPA 系列教程6-单向多对多的更多相关文章
- JPA 系列教程7-双向多对多
双向多对多的ddl语句 同单向多对多表的ddl语句一致 Student package com.jege.jpa.many2many; import java.util.HashSet; import ...
- JPA 系列教程3-单向多对一
JPA中的@ManyToOne 主要属性 - name(必需): 设定"many"方所包含的"one"方所对应的持久化类的属性名 - column(可选): 设 ...
- JPA 系列教程4-单向一对多
JPA中的@OneToMany @Target({METHOD, FIELD}) @Retention(RUNTIME) public @interface OneToMany { Class tar ...
- JPA 系列教程5-双向一对多
双向一对多的ddl语句 同单向多对一,单向一对多表的ddl语句一致 Product package com.jege.jpa.one2many; import javax.persistence.En ...
- JPA 系列教程21-JPA2.0-@MapKeyColumn
@MapKeyColumn 用@JoinColumn注解和@MapKeyColumn处理一对多关系 ddl语句 CREATE TABLE `t_employee` ( `id` bigint(20) ...
- JPA 系列教程17-继承-独立表-TABLE_PER_CLASS
PerTable策略 每个具体的类一个表的策略 举例 这种映射策略每个类都会映射成一个单独的表,类的所有属性,包括继承的属性都会映射成表的列. 这种映射策略的缺点是:对多态关系的支持有限,当查询涉及到 ...
- JPA 系列教程16-继承-联合子类-JOINED
联合子类策略 这种情况下子类的字段被映射到各自的表中,这些字段包括父类中的字段,并执行一个join操作来实例化子类. 举例 如果实体类Teacher继承实体类Person,实体类Student也继承自 ...
- JPA 系列教程13-复合主键-@EmbeddedId+@Embeddable
复合主键 指多个主键联合形成一个主键组合 需求产生 比如航线一般是由出发地及目的地确定,如果要确定唯一的航线就可以用出发地和目的地一起来表示 ddl语句 同复合主键-2个@Id和复合主键-2个@Id+ ...
- JPA 系列教程12-复合主键-2个@Id+@IdClass
复合主键 指多个主键联合形成一个主键组合 需求产生 比如航线一般是由出发地及目的地确定,如果要确定唯一的航线就可以用出发地和目的地一起来表示 ddl语句 同复合主键-2个@Id一样 Airline p ...
随机推荐
- 戏说HTML5(转)
如果有非技术人员问你,HTML5是什么,你会怎么回答? 新的HTML规范... 给浏览器提供了牛逼能力,干以前不能干的事...(确切地说应该是给浏览器规定了许多新的接口标准,要求浏览器实现牛逼的功能. ...
- (转)eclipse自动补全的设置
如果你用过Visual Studio的自动补全功能后,再来用eclipse的自动补全功能,相信大家会有些许失望. 但是eclipse其实是非常强大的,eclipse的自动补全没有VS那么好是因为ecl ...
- Python虚拟环境的配置
Python中,配置虚拟环境主要是为了防止版本之间的冲突,我是这么理解的: 1.用虚拟环境可以在一个电脑中使用多个Python解释器以及扩展: 2.可以方便的在同一台电脑中使用多个版本的代码. 虚拟环 ...
- HttpPost与HttpVerbs.Post属性的区别
1. the HttpPost attribute is a short for the HttpVerbs.Post one but since MVC 2.0. 从MVC 2.0之后HttpPos ...
- Docker私有仓库1
一.搭建私有仓库 #环境 Ip 192.168.0.34 X86云主机 [root@lh- /]# uname -a Linux lh- -.el7.x86_64 # SMP Thu Mar :: U ...
- centos 7上搭建HDP2.3集群
centos 7上安装 cat /etc/redhat-release
- HUST 1352 Repetitions of Substrings(字符串)
Repetitions of Substrings Description The “repetitions” of a string S(whose length is n) is a maximu ...
- OMCS开发手册(01) -- 多媒体设备管理器
我们在前面一篇文章中提到:任何一个OMCS的Client都有两种身份,Owner和Guest.多媒体设备管理器工作于OMCS客户端,并以Owner的身份管理本地所有的多媒体设备.多媒体设备管理器对象是 ...
- java中的Volatile 变量
Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”:与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少, ...
- 飞雪桌面日历软件 V8.6 免费绿色版
软件名称: 飞雪桌面日历软件软件语言: 简体中文授权方式: 免费软件运行环境: Win7 / Vista / Win2003 / WinXP / Win2008软件大小: 4MB图片预览: 软件简介: ...