JPA 系列教程7-双向多对多
双向多对多的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();
}
}
其他关联项目
- * JPA 系列教程6-单向多对多*
http://blog.csdn.net/je_ge/article/details/53495237
源码地址
如果觉得我的文章对您有帮助,请打赏支持。您的支持将鼓励我继续创作!谢谢!
JPA 系列教程7-双向多对多的更多相关文章
- JPA 系列教程3-单向多对一
JPA中的@ManyToOne 主要属性 - name(必需): 设定"many"方所包含的"one"方所对应的持久化类的属性名 - column(可选): 设 ...
- JPA 系列教程6-单向多对多
JPA中的@ManyToMany @ManyToMany注释表示模型类是多对多关系的一端. @JoinTable 描述了多对多关系的数据表关系. name 属性指定中间表名称 joinColumns ...
- 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 系列教程10-双向一对一关联表
双向一对一关联表的ddl语句 CREATE TABLE `t_person` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255 ...
- JPA 系列教程9-双向一对一唯一外键
双向一对一唯一外键的ddl语句 CREATE TABLE `t_person` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(25 ...
- 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也继承自 ...
随机推荐
- openwrt 的 inittab
文件位于 /etc/inittab, 内容如下: root@hbg:/# cat /etc/inittab ::sysinit:/etc/init.d/rcS S boot::shutdown:/et ...
- 常量指针(const X*)和指针常量(X* const)
const X* 类型的指针(指向常量的指针),此指针的地址是一个变量,是可以修改的:但其所指向的内容是常量,是不可以修改的. 例如: 1: char name[5] = "lisi&quo ...
- stl 生产全排列 next_permutation
#include<stdio.h>#include<algorithm>using namespace std;int main(){ int n,p[10]; scanf(& ...
- 浅谈SharePoint 2013 站点模板开发 转载自http://www.cnblogs.com/jianyus/p/3511550.html
一直以来所接触的SharePoint开发,都是Designer配合Visual Studio,前者设计页面,后者开发功能,相互合作,完成SharePoint网站开发.直到SharePoint 2013 ...
- "urllib"库的学习
在习题—41遇到这个模块/库, 有兴趣的参考下面这个网址: http://blog.sina.com.cn/s/blog_b369b20d0101kb7m.html # coding: utf-8 i ...
- ECOS-Ecstore 后台管理地址修改
ECStore默认出厂的后台管理地址是: http://域名/index.php/shopadmin http://域名/shopadmin [配置过rewrite后,并开启伪静态] 如果想要更个性的 ...
- Saltstack 服务器基本安装
Salt介绍 Salt是一个基础平台管理工具 Salt是一个配置管理系统,能够维护预定义状态的远程节点 Salt是一个分布式远程执行系统,用来在远程节点上执行命令和查询数据 Salt核心功能 使命令发 ...
- php自动运行
<?php ignore_user_abort(); //即使Client断开(如关掉浏览器),PHP脚本也可以继续执行. set_time_limit(0); //执行时间为无限制,php默认 ...
- 获取集合、数组后要判断为空的必要性以及根据构造器创建对象后不是null的证实
在开发过程中,凡是获取到一个集合对象,在利用或者说遍历这个集合对象之前,都要进行是否为null以及size()>0的判断,但是如果size()>0的话,不是就已经可以说明此集合对象不为nu ...
- Python 正则表达式学习笔记
本文介绍了Python对于正则表达式的支持,包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例.本文的内容不包括如何编写高效的正则表达式.如何优化正则表达式,这些主题请查看其他教程 ...