`

JPA多对多

阅读更多

维护端注解

@ManyToMany (cascade = CascadeType.REFRESH)

@JoinTable (//关联表

                   name =  "student_teacher" , //关联表名

                   inverseJoinColumns =  @JoinColumn (name =  "teacher_id" ),//被维护端外键

                   joinColumns =  @JoinColumn (name =  "student_id" ))//维护端外键

被维护端注解

@ManyToMany(

                   cascade = CascadeType.REFRESH,

                   mappedBy = "teachers",//通过维护端的属性关联

                   fetch = FetchType.LAZY)

关系维护端删除时,如果中间表存在些纪录的关联信息,则会删除该关联信息;

关系被维护端删除时,如果中间表存在些纪录的关联信息,则会删除失败 .

 

 

以学生和老师的对应关系为例。一个学生可以拥有多个老师,一个老师也可以拥有多个学生。

学生实体类

package com.taoistwar.jpa.entity.manytomany;

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

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;

@Entity
public class Student {
	private Integer id;
	private String name;
	private Set<Teacher> teachers = new HashSet<Teacher>();

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(nullable = false, length = 16)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@ManyToMany(cascade = CascadeType.REFRESH)
	@JoinTable(name = "student_teacher", inverseJoinColumns = @JoinColumn(name = "teacher_id"), joinColumns = @JoinColumn(name = "student_id"))
	public Set<Teacher> getTeachers() {
		return teachers;
	}

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

	public void addTeacher(Teacher teacher) {
		this.teachers.add(teacher);
	}

	public void removeTeachers(Teacher teacher) {
		this.teachers.remove(teacher);
	}

}

 重点在于:

@ManyToMany(cascade = CascadeType.REFRESH)
	@JoinTable(name = "student_teacher", inverseJoinColumns = @JoinColumn(name = "teacher_id"), joinColumns = @JoinColumn(name = "student_id"))
	public Set<Teacher> getTeachers() {
		return teachers;
	}

 老师实体类

package com.taoistwar.jpa.entity.manytomany;

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.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

@Entity
public class Teacher {
	private Integer id;
	private String name;
	private Set<Student> students = new HashSet<Student>();

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(nullable = false, length = 16)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@ManyToMany(cascade = CascadeType.REFRESH, mappedBy = "teachers", fetch = FetchType.LAZY)
	public Set<Student> getStudents() {
		return students;
	}

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

      @Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Teacher other = (Teacher) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
}

 重点在于:

@ManyToMany(cascade = CascadeType.REFRESH, mappedBy = "teachers", fetch = FetchType.LAZY)
	public Set<Student> getStudents() {
		return students;
	}

 拥有mappedBy注解的实体类为关系被维护端,另外的实体类为关系维护端的。顾名思意,关系的维护端对关系(在多对多为中间关联表)的CRUD做操作。关系的被维护端没有该操作,不能维护关系。

测试类

package com.taoistwar.jpa.entity.manytomany;

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

import org.junit.Test;

public class ManyToMany {
	@Test
	public void save() {
		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("JPAPU");
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		Student student = new Student();
		student.setName("小李");
		Teacher teacher = new Teacher();
		teacher.setName("大李");
		em.persist(student);
		em.persist(teacher);
		em.getTransaction().commit();
		emf.close();
	}
	
	@Test
	public void bind() {
		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("JPAPU");
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		Student student = em.find(Student.class, 1);
		Teacher teacher = em.find(Teacher.class, 1);
		student.addTeacher(teacher);
		em.persist(student);
		em.getTransaction().commit();
		emf.close();
	}
	
	@Test
	public void unbind() {
		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("JPAPU");
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		Student student = em.find(Student.class, 1);
		Teacher teacher = em.find(Teacher.class, 1);
		student.removeTeachers(teacher);
		em.persist(student);
		em.getTransaction().commit();
		emf.close();
	}
	
	@Test
	public void removeTeacher() {
		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("JPAPU");
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		// 关系被维护端删除时,如果中间表存在些纪录的关联信息,则会删除失败
		em.remove(em.getReference(Teacher.class, 1));
		em.getTransaction().commit();
		emf.close();
	}
	
	@Test
	public void removeStudent() {
		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("JPAPU");
		EntityManager em = emf.createEntityManager();
		em.getTransaction().begin();
		// 关系维护端删除时,如果中间表存在些纪录的关联信息,则会删除该关联信息
		em.remove(em.getReference(Student.class, 1));
		em.getTransaction().commit();
		emf.close();
	}
	
}

 

 

 

 

 

 

 

 

  • JPA.zip (5.7 MB)
  • 下载次数: 182
分享到:
评论
1 楼 nforce_com 2011-05-12  
写的很好,学习了!不过Student 一般情况下不会删除所有的Teacher ,仅会删除某个Teacher ,这里面没太讲清楚,下面加上部分代码:
.........举例,因环境不同略去.......

public void doDeleteDetail(ActionEvent event) {

.........举例,因环境不同略去.......
Set<Teacher > set = getInstance().getTeacher();
Iterator<Teacher > itr = set.iterator();
while (itr.hasNext()) {
Teacher m = itr.next();
if (item.getId().equals(m.getId())) {
log.info("---RequestMap:#0", m.getId());
set.remove(m);
// 实体的改变同步到数据库
getEntityManager().merge(getInstance());
// 会话没有结束,手动flush
getEntityManager().flush();
return;
}
}
}

相关推荐

    JPA多对多Demo

    **JPA多对多关联关系详解** 在Java开发中,对象关系映射(ORM)框架如JPA(Java Persistence API)极大地简化了数据库操作。JPA是Java EE的一部分,为开发者提供了一种标准的方式来处理数据库操作,使得我们可以用...

    JPA一对一,一对多,多对多关系映射

    本篇将深入探讨JPA中的一对一(OneToOne)、一对多(OneToMany)以及多对多(ManyToMany)关系映射。 ### 1. JPA 一对一(OneToOne)关系映射 **概念**:一对一关系意味着两个实体之间存在唯一的关联,一个实体...

    13_jpa多对多双向关联实体定义与注解

    "13_传智播客JPA详解"系列教程涵盖了JPA的诸多方面,而"13_传智播客JPA详解_JPA中的多对多双向关联实体定义与注解设置"这一部分则专门聚焦于多对多关联的实践。 在关系型数据库中,多对多关联是最为复杂的一种关系...

    JPA中的多对多双向关联实体定义与注解设置

    在Java Persistence API (JPA) 中,多对多(ManyToMany)关系是表示两个实体之间复杂关联的一种方式。这种关联允许一个实体实例可以与多个其他实体实例相关联,反之亦然。例如,一个学生可以选修多门课程,一门课程...

    自己做的一个jpa多对多映射的一个例子

    刚学完了hibernate和ejb,自己又自学了下jpa,看了黎活明老师的视频,自己做了个多对多的例子,希望可以对你学习有所帮助,有心人可以联系我QQ770256061!

    14_传智播客JPA详解_JPA中的多对多双向关联的各项关系操作

    在JPA中,多对多(Many-to-Many)关联是一种常见的关系类型,适用于描述两个实体之间复杂的关系。本教程将深入探讨JPA中多对多双向关联的各个方面及其操作。 在数据库中,多对多关联意味着一个实体可以与多个其他...

    JPA中实现双向多对多的关联关系示例代码

    本文将深入探讨在JPA中如何实现双向多对多的关联关系,并提供相关的示例代码。 首先,我们需要了解多对多关联关系的基本概念。在关系型数据库中,两个实体之间可能存在多对多的关系,意味着每个实例可以从一个实体...

    jpa的实体映射关系7种

    在单向多对多关系中,一个实体可以关联多个其他实体,而这些实体并不知道这个关联。使用`@ManyToMany`注解,关联表通常由JPA自动创建,除非自定义了`@JoinTable`。 7. **双向多对多**: 双向多对多是最复杂的关系...

    09_JPA详解_使用JPQL语句进行查询.zip

    5. **关联(Associations)**:JPA支持一对一、一对多、多对一和多对多的关系映射。使用`@OneToOne`、`@OneToMany`、`@ManyToOne`和`@ManyToMany`注解来定义实体之间的关联。 6. **继承(Inheritance)**:JPA支持...

    JPA一对多和多对一关系

    **JPA一对多和多对一关系详解** Java Persistence API(JPA)是Java平台上的一个标准,用于处理对象关系映射(ORM),使得开发者可以使用面向对象的方式来操作数据库。在JPA中,实体间的关系映射是核心概念之一,...

    jpa例子jpajpa

    8. **多态性(Polymorphism)**: JPA支持继承和多态性,使得你可以定义一个基类,然后多个子类继承它并有自己的数据库表。 在"apache-openjpa-1.2.0-source"这个压缩包中,包含了Apache OpenJPA项目的源代码。Open...

    11_传智播客JPA详解_JPA中的一对多延迟加载与关系维护

    例如,一个学生可以属于多个班级(多对一),而一个班级可以包含多个学生(一对多)。在JPA中,我们通过在实体类上使用`@OneToMany`注解来定义这种关系。这个注解允许我们将一个实体的集合属性映射到另一个实体的...

    Spring Boot+Jpa多数据源配置Demo(支持不同数据库)

    总结来说,Spring Boot + JPA 的多数据源配置需要对Spring的配置机制有深入理解,包括自动配置、bean的创建、数据源的切换等。同时,合理组织实体类和数据库访问层,确保代码的可维护性和扩展性。这个名为`...

    11_JPA详解_JPA中的一对多延迟加载与关系维护.zip

    本资料主要探讨的是JPA中的一对多关系以及延迟加载机制,这两部分是JPA使用中的关键概念。 **一对多关系** 在关系数据库中,一对多关系是最常见的一种关联类型。例如,一个部门可以有多名员工,而每个员工只能属于...

    jpa--9.单向多对一

    在Java Persistence API (JPA) 中,"单向多对一"关系是一种常见的对象关系映射(ORM)设计模式,用于表示实体之间的关联。在这个模式中,一个实体("多"端)可以引用另一个实体("一"端),但被引用的实体并不持有对...

    使用springboot + JPA / MyBatis 实现多数据源动态切换

    3. **Spring Data JPA**:Spring Boot中的Spring Data JPA模块,提供了对JPA的便捷支持,包括自动配置、Repository接口的简化操作等。 **二、多数据源配置** 1. **配置文件**:在Spring Boot的application....

    JPA双向一对多实例配置

    JPA中双向一对多实体Bean的属性配置,包括延迟加载,级联删除等

    springboot+JPA 多数据源配置

    通过以上步骤,你就可以在Spring Boot项目中成功配置并使用JPA进行多数据源操作了。这种方式允许你灵活地管理不同数据库的数据,对于复杂的分布式系统和多租户应用特别有用。在实际开发中,还可能需要考虑数据源的...

    JPA源文件/jpa学习

    JPA 2.0引入了许多增强功能,比如支持@OneToMany和@ManyToMany关系的双向映射,新增了@Temporal注解以处理日期和时间,增强了Criteria API,引入了@SecondaryTable注解以支持多表映射,还引入了Entity Graph来优化...

    spring jpa操作数据库 级联数据 hibernate

    - "spring-framework-2.5.zip"和"JpaManytoMany.zip"可能包含Spring 2.5版本的资料和多对多关联的JPA示例。 了解并熟练掌握这些知识点,将有助于开发人员更高效地构建基于Spring JPA的数据库驱动应用,同时也能更...

Global site tag (gtag.js) - Google Analytics