双向多对多的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

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



JPA 系列教程7-双向多对多的更多相关文章

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

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

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

    JPA中的@ManyToMany @ManyToMany注释表示模型类是多对多关系的一端. @JoinTable 描述了多对多关系的数据表关系. name 属性指定中间表名称 joinColumns ...

  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 系列教程10-双向一对一关联表

    双向一对一关联表的ddl语句 CREATE TABLE `t_person` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255 ...

  6. JPA 系列教程9-双向一对一唯一外键

    双向一对一唯一外键的ddl语句 CREATE TABLE `t_person` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(25 ...

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

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

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

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

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

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

随机推荐

  1. Java 反射 Class对象

    Java 反射 Class对象 @author ixenos 关键字:RTTI.动态绑定.动态加载.获得Class引用.泛型Class引用.newInstance的坑.JVM中的泛型类型信息 RTTI ...

  2. Openjudge-计算概论(A)-回文串判断

    描述: 任意给定一个非空的字符串,判断其是否是回文串.回文串是指正向看和反向看均相等的串,如AbcDcbA和cDDc.如果是回文串,则输出1,否则,输出0 输入长度不小于1不大于100的字符串输出如果 ...

  3. ios 将图片变成圆形

    #pragma mark - 将图片转换成圆形 -(UIImage*) circleImage:(UIImage*) image withParam:(CGFloat) inset { UIGraph ...

  4. js常用API 数据类型 基本类型,基本包装类型,引用类型 Object String Array Boolean Number Date Math

    数据类型 变量.作用域及内存 基础类型(primitive value):Undefined.Null.Boolean.Number和String.这些类型在内存中分别占用固定大小的空间,他们的值保存 ...

  5. ACE_Event_Handler:事件响应入口

    1:ACE_Event_Handler类 头文件“Event_Handler.h” 在ACE Reactor框架中,ACE_Event_Handler是所有事件处理器的基类.ACE_Event_Han ...

  6. Android 内存监测工具 DDMS --> Heap(转)

    DDMS 的全称是Dalvik Debug Monitor Service,它为我们提供例如:为测试设备截屏,针对特定的进程查看正在运行的线程以及堆信息.Logcat.广播状态信息.模拟电话呼叫.接收 ...

  7. POJ 2062 HDU 1528 ZOJ 2223 Card Game Cheater

    水题,感觉和田忌赛马差不多 #include<cstdio> #include<cstring> #include<cmath> #include<algor ...

  8. Spring的后置处理器BeanPostProcessor

    一.BeanPostProcessor接口的作用 如果我们需要在Spring容器完成Bean的实例化.配置和其他的初始化前后添加一些自己的逻辑处理,我们就可以定义一个或者多个BeanPostProce ...

  9. 《C++ Primer》之重载操作符与转换(下)

    转换与类类型 可用一个实参调用的非 explicit 构造函数定义一个隐式转换.当提供了实参类型的对象而需要一个类类型的对象时,编译器将使用该转换.这种构造函数定义了到类类型的转换.除了定义到类类型的 ...

  10. html元素中class属性值多个空格分格是什么意思?

    即指定多个class,这是bootstrap常干的事,比如 <div class="alert alert-info"> 请问,这两个class之间的关系是什么,二者的 ...