随笔 - 1357  文章 - 0  评论 - 1104  阅读 - 1941万

jpa多对多映射案例

学生和老师就是多对多的关系。一个学生有多个老师,一个老师教多个学生。多对多映射采取中间表连接的映射策略,建立的中间表将分别引入两边的主键作为外键。jpa 对于中间表的元数据提供了可配置的方式,用户可以自定义中间表的表名,列名。

下面就以学生和老师为例介绍多对多映射关系的实例开发

 

Student实体类 

复制代码
package com.ljq.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

@SuppressWarnings(
"serial")
@Entity
public class Student implements java.io.Serializable {
/** 学生ID **/
private Integer studentid;
/** 学生姓名 **/
private String name;
private Set<Teacher> teachers=new HashSet<Teacher>();

public Student() {
super();
}

public Student(String name) {
super();
this.name = name;
}

@Id
@GeneratedValue
public Integer getStudentid() {
return studentid;
}

public void setStudentid(Integer studentid) {
this.studentid = studentid;
}

@Column(nullable
=false,length=32)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

//@ManyToMany注释表示Student是多对多关系的一边,mappedBy属性定义了Student为双向关系的维护端
//Teacher表是关系的维护者,owner side,有主导权,它有个外键指向Student表。
@ManyToMany(mappedBy = "students")
public Set<Teacher> getTeachers() {
return teachers;
}

public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}

}
复制代码

Teacher实体类 

复制代码
package com.ljq.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
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;

@SuppressWarnings(
"serial")
@Entity
public class Teacher implements java.io.Serializable {
/** 教师ID **/
private Integer teacherid;
/** 教师姓名 **/
private String name;
private Set<Student> students=new HashSet<Student>();

public Teacher() {
super();
}

public Teacher(String name) {
super();
this.name = name;
}

@Id
@GeneratedValue
public Integer getTeacherid() {
return teacherid;
}

public void setTeacherid(Integer teacherid) {
this.teacherid = teacherid;
}

@Column(nullable
=false,length=32)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

//@ManyToMany注释表示Teacher是多对多关系的一端。
//@JoinTable描述了多对多关系的数据表关系。name属性指定中间表名称,joinColumns定义中间表与Teacher表的外键关系。
//中间表Teacher_Student的Teacher_ID列是Teacher表的主键列对应的外键列,inverseJoinColumns属性定义了中间表与另外一端(Student)的外键关系。
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinTable(name
= "Teacher_Student",
joinColumns
= { @JoinColumn(name = "Teacher_ID", referencedColumnName = "teacherid") },
inverseJoinColumns
= { @JoinColumn(name = "Student_ID", referencedColumnName = "studentid") })
public Set<Student> getStudents() {
return students;
}

public void setStudents(Set<Student> students) {
this.students = students;
}

/**
* 添加学生
*
*
@param student
*/
public void addStudent(Student student) {
if (!this.students.contains(student)) {
this.students.add(student);
student.setTeacher(this);
}
}

/**
* 删除学生
*
*
@param student
*/
public void removeStudent(Student student) {
if(this.students.contains(student)){
student.setTeacher(null);
this.students.remove(student);
}
}
}
复制代码

ManyToManyTest测试类 

复制代码
package com.ljq.test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.junit.Test;

import com.ljq.entity.Student;
import com.ljq.entity.Teacher;


public class ManyToManyTest {

@Test
public void save() {
EntityManagerFactory factory
= Persistence.createEntityManagerFactory("ljq");
EntityManager em
=factory.createEntityManager();
em.getTransaction().begin();

em.persist(
new Teacher("张老师"));
em.persist(
new Student("小张"));

em.getTransaction().commit();
em.close();
factory.close();

}

/**
* 为老师添加一个学生
*
*/
@Test
public void build() {
EntityManagerFactory factory
= Persistence.createEntityManagerFactory("ljq");
EntityManager em
=factory.createEntityManager();
em.getTransaction().begin();

Teacher teacher
= em.find(Teacher.class, 2);
teacher.addStudent(em.getReference(Student.
class, 2));

em.getTransaction().commit();
em.close();
factory.close();
}

/**
* 解除学生跟老师的关系
*
*/
@Test
public void remove() {
EntityManagerFactory factory
= Persistence.createEntityManagerFactory("ljq");
EntityManager em
=factory.createEntityManager();
em.getTransaction().begin();

Teacher teacher
= em.find(Teacher.class, 2);
teacher.removeStudent(em.getReference(Student.
class, 2));

em.getTransaction().commit();
em.close();
factory.close();

}

/**
* 删除学生,因为学生不是关系维护者,所以需要先手工解除老师与学生的关联,然后再删除学生
*
*/
@Test
public void deleteStudent() {
EntityManagerFactory factory
= Persistence.createEntityManagerFactory("ljq");
EntityManager em
=factory.createEntityManager();
em.getTransaction().begin();

Teacher teacher
= em.find(Teacher.class, 2);
Student student
= em.getReference(Student.class, 2);
teacher.removeStudent(student);
//手工解除老师与学生的关系
em.remove(student); //删除学生

em.getTransaction().commit();
em.close();
factory.close();
}

/**
* 删除老师,因为老师是关系维护者,所以可以直接解除老师与学生的关系,不用我们手工解除
*
*/
@Test
public void deleteTeacher() {
EntityManagerFactory factory
= Persistence.createEntityManagerFactory("ljq");
EntityManager em
=factory.createEntityManager();
em.getTransaction().begin();

em.remove(em.getReference(Teacher.
class, 3));

em.getTransaction().commit();
em.close();
factory.close();

}

/**
* 用来判断映射是否成功
*
*/
@Test
public void test() {
EntityManagerFactory factory
= Persistence.createEntityManagerFactory("ljq");
factory.close();
}

}
复制代码
posted on   Ruthless  阅读(19861)  评论(3编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
< 2011年1月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示