`
林里风咏
  • 浏览: 12870 次
  • 性别: Icon_minigender_1
  • 来自: 湖南长沙
最近访客 更多访客>>
社区版块
存档分类
最新评论

JPA中多对多的实现

    博客分类:
  • JPA
阅读更多
我是用自己搭建的一个seam工程,去实现JPA中的多对多的关系
示例背景:
一个学生可以有多个老师,一个老师也可以有多个学生,这是一个我们都知道事实


先自己建一个seam工程,不要用Eclipse自动自成,那样会有很多问题,所以还是自己建。
目录结构如下
[img][/img]

1.Student.java类   这是关系维护端
package com.cyberwise.jpa.many2many;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Version;

@SuppressWarnings("serial")
@Entity
@Table(name = "students")
public class Student implements Serializable {

	@Version
	private long version;

	@Id
	@GeneratedValue
	private int stu_id;

	private String stu_name;

	private String sex;

	private int age;

	@ManyToMany(cascade = CascadeType.REFRESH)
	@JoinTable(name = "stu_tea", inverseJoinColumns = @JoinColumn(name = "teacher_id", referencedColumnName = "tea_id"), // 外键名
	joinColumns = @JoinColumn(name = "student_id", referencedColumnName = "stu_id"))
	// 关系维护端定义
	private Set<Teacher> teacher = new HashSet<Teacher>();

	public Student() {

	}

	public long getVersion() {
		return version;
	}

	public void setVersion(long version) {
		this.version = version;
	}

	public int getStu_id() {
		return stu_id;
	}

	public void setStu_id(int stu_id) {
		this.stu_id = stu_id;
	}

	public String getStu_name() {
		return stu_name;
	}

	public void setStu_name(String stu_name) {
		this.stu_name = stu_name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Set<Teacher> getTeacher() {
		return teacher;
	}

	public void setTeacher(Set<Teacher> teacher) {
		this.teacher = teacher;
	}

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

	/*
	 * 凭什么判断teacher在集合teachers中呢?是根据teacher的id。
	 * 这就要求必要重写Teacher.java的hasCode和equals方法
	 * ,通过这两个方法来判断对象是否相等。
	 */
	public void removeTeacher(Teacher teachers) {
		this.teacher.remove(teachers);
	}

}



2.Teacher.java类   这是关系被维护端
package com.cyberwise.jpa.many2many;

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

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Version;

@Entity
@Table(name="teachers")
public class Teacher {
	
	@Version
	private long version;
	
	@Id
	@GeneratedValue
	private int tea_id;
	
	private String tea_name;
	
	private String sex;
	
	private int age;
	
	@ManyToMany(cascade=CascadeType.REFRESH,mappedBy="teacher")
	private Set<Student> student = new HashSet<Student>();

	public long getVersion() {
		return version;
	}

	public void setVersion(long version) {
		this.version = version;
	}

	public int getTea_id() {
		return tea_id;
	}

	public void setTea_id(int tea_id) {
		this.tea_id = tea_id;
	}

	public String getTea_name() {
		return tea_name;
	}

	public void setTea_name(String tea_name) {
		this.tea_name = tea_name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Set<Student> getStudent() {
		return student;
	}

	public void setStudent(Set<Student> student) {
		this.student = student;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((sex == null) ? 0 : sex.hashCode());
		result = prime * result + ((student == null) ? 0 : student.hashCode());
		result = prime * result + tea_id;
		result = prime * result
				+ ((tea_name == null) ? 0 : tea_name.hashCode());
		result = prime * result + (int) (version ^ (version >>> 32));
		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 (age != other.age)
			return false;
		if (sex == null) {
			if (other.sex != null)
				return false;
		} else if (!sex.equals(other.sex))
			return false;
		if (student == null) {
			if (other.student != null)
				return false;
		} else if (!student.equals(other.student))
			return false;
		if (tea_id != other.tea_id)
			return false;
		if (tea_name == null) {
			if (other.tea_name != null)
				return false;
		} else if (!tea_name.equals(other.tea_name))
			return false;
		if (version != other.version)
			return false;
		return true;
	}

}



3.Many2ManyTest.java类   这是测试方法
package com.cyberwise.jpa.many2many;

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

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

import org.jboss.seam.annotations.In;
/*manager.find(Teacher.class, 5);像这样的参数要根据自己的项目来
*/
public class Many2ManyTest {

	@In
	EntityManagerFactory factory;

	@In
	EntityManager manager;

	/**
	 * 执行第一次,一个学生对应一个老师,即一个新学生与一个新老师
	 */
	public void save() {
		factory = Persistence.createEntityManagerFactory("test");
		manager = factory.createEntityManager();
		manager.getTransaction().begin();

		Student s = new Student();
		s.setStu_name("小静");
		s.setAge(20);
		s.setSex("女");

		Teacher t = new Teacher();
		t.setTea_name("钟老师");
		t.setAge(25);
		t.setSex("男");

		Set<Teacher> tea = new HashSet<Teacher>();
		tea.add(t);

		Set<Student> stu = new HashSet<Student>();
		stu.add(s);

		t.setStudent(stu);
		s.setTeacher(tea);

		manager.persist(t);
		manager.persist(s);

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

	/**
	 * 这是添加第二个学生,但是他也是对应着第一个老师 是因为这个老师已经存在了,但是学生不存在
	 */
	public void saveSecond() {
		factory = Persistence.createEntityManagerFactory("test");
		manager = factory.createEntityManager();
		manager.getTransaction().begin();

		Student s = new Student();
		s.setStu_name("小美");
		s.setAge(19);
		s.setSex("女");

		Set<Student> stu = new HashSet<Student>();
		stu.add(s);

		/* 这是先查出那个老师,在把老师放到学生中去 */
		Teacher teacher = manager.find(Teacher.class, 6);
		s.addTeacher(teacher);

		manager.persist(s);

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

	/**
	 * 5号学生对应1号老师和四号老师 学生存在,老师也存在
	 */
	public void buildST() {
		factory = Persistence.createEntityManagerFactory("test");
		manager = factory.createEntityManager();
		manager.getTransaction().begin();

		Teacher teacher = manager.find(Teacher.class, 5);
		Student student = manager.find(Student.class, 4);
		student.addTeacher(teacher);

		manager.merge(student);

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

	/**
	 * 老师查询学生
	 */
	public void selectStudent() {
		factory = Persistence.createEntityManagerFactory("test");
		manager = factory.createEntityManager();

		Teacher te = manager.find(Teacher.class, 5);// 这是查询1号老师对应的学生
		Set<Student> stu = te.getStudent();
		System.out.println(te.getTea_name() + "的学生有:");
		for (Iterator<Student> iterator = stu.iterator(); iterator.hasNext();) {
			Student s = iterator.next();
			System.out.println(s.getStu_name());
		}

		manager.close();
		factory.close();
	}

	/**
	 * 学生查询老师
	 */
	public void selectTeacher() {
		factory = Persistence.createEntityManagerFactory("test");
		manager = factory.createEntityManager();

		Student stu = manager.find(Student.class, 5);
		Set<Teacher> tea = stu.getTeacher();
		System.out.println(stu.getStu_name() + "的老师有:");
		for (Iterator<Teacher> iterator = tea.iterator(); iterator.hasNext();) {
			Teacher t = iterator.next();
			System.out.println(t.getTea_name());
		}

		manager.close();
		factory.close();
	}

	/**
	 * 解除老师与学生的关系
	 */
	public void removeS_T() {
		factory = Persistence.createEntityManagerFactory("test");
		manager = factory.createEntityManager();
		manager.getTransaction().begin();

		// 首先得到学生,因为学生是关系维护端,通过关系维护端建立关系
		Student s = manager.find(Student.class, 12);// 解除1号学生与1号老师的关联

		// 这就表示解除了学生与老师间的关系
		// 所谓解除跟老师的关系,就是把老师从集合里面删去。
		// 解除关系,体现在JDBC上面,就是在中间表删除一条记录。
		s.removeTeacher(manager.getReference(Teacher.class, 6));

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

	/**
	 * 删除老师,老师与学生已经建立关系
	 */
	public void delectTeacher() {
		factory = Persistence.createEntityManagerFactory("test");
		manager = factory.createEntityManager();
		manager.getTransaction().begin();

		// 要删除老师,先把与老师有关联的学生找出来,解除他们的关系才可以
		Student student = manager.find(Student.class, 11);
		Teacher teacher = manager.getReference(Teacher.class, 6);

		/*
		 * 不能这样写, manager.remove(em.getReference(Teacher.class, 1));
		 * 因为不需要发生装载行为,只需要一个托管状态的实体,所以gerReference可以提供
		 */

		// student是关系维护端,有权利删除外键,只要在对象中删除了teacher,那么中间表中相关外键记录也就被删除了。
		student.removeTeacher(teacher);// 这是解除他们的关系
		manager.remove(teacher);// 这是删除老师

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

	/**
	 * 删除学生,老师与学生有关联
	 */
	public void delectStudent() {
		factory = Persistence.createEntityManagerFactory("test");
		manager = factory.createEntityManager();
		manager.getTransaction().begin();

		/* student端是关系维护端,是可以直接删除的,不需要解除外键 */
		Student student = manager.getReference(Student.class, 13);
		manager.remove(student);

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

	public static void main(String[] args) {

		Many2ManyTest test = new Many2ManyTest();
		// test.save();
		// test.saveSecond();
		// test.buildST();
		// test.selectStudent();
		// test.selectTeacher();
		// test.removeS_T();
		// test.delectTeacher();
		test.delectStudent();
	}

}


  • 大小: 4.4 KB
0
0
分享到:
评论

相关推荐

    JPA多对多Demo

    本示例中的“JPA多对多Demo”是一个具体的实践案例,展示了如何在JPA中实现多对多关联关系,以及对应的增删改查方法。 多对多关联是现实世界中常见的一种关系类型,例如教师和学生之间的关系,一个教师可以教多个...

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

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

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

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

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

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

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

    本教程将深入探讨JPA中多对多双向关联的各个方面及其操作。 在数据库中,多对多关联意味着一个实体可以与多个其他实体相关联,反之亦然。例如,学生和课程之间的关系就是一个典型的多对多关系:一个学生可以选修多...

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

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

    Hibernate annotation JPA 一对多,多对多

    在本主题中,我们将深入探讨使用Hibernate注解来实现JPA的一对多、多对多和多对一的关系映射。 1. **一对多关系**: 在现实世界中,一个老师可以教多个学生,或者一个班级可以包含多个学生,这就是典型的一对多...

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

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

    JPA一对多和多对一关系

    在JPA中,实体间的关系映射是核心概念之一,其中一对多(OneToMany)和多对一(ManyToOne)是两种常见的关系类型。 ### 一对多关系(OneToMany) 在数据库中,一对多关系意味着一个表中的记录可以与另一个表中的多...

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

    要在一对多关系中实现延迟加载,我们需要在`@OneToMany`注解上添加`fetch = FetchType.LAZY`。这告诉JPA应该在需要时才去加载关联的实体集合,而不是在加载父实体时一并加载。然而,需要注意的是,由于Java的反射...

    Spring Data JPA中文文档[1.4.3]_springdatajpa_erlang_waitxpf_

    Spring Data JPA 提供了内置的支持,可以在查询方法中通过 `Pageable` 参数实现分页和排序。 5. **Auditing**:Spring Data JPA 提供了审计功能,可以自动记录实体的创建时间和修改时间。这可以通过 `@CreatedDate`...

    springboot结合jpa实现分页,动态多条件查询

    在本文中,我们将深入探讨如何在Spring Boot项目中利用Java Persistence API (JPA) 实现分页和动态多条件查询,并结合Thymeleaf模板引擎展示数据。Spring Boot以其简化配置和快速启动的优势,已经成为现代Java开发的...

    jpa例子jpajpa

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

    JPA中的一对多双向关联与级联操作

    在Java Persistence API (JPA) 中,一对多关联是一种常见的关系映射,它表示一个实体可以与多个其他实体相关联。这种关联在数据库层面通常通过外键实现,而在JPA中,我们通过注解来配置这种关系。这篇博客将深入探讨...

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

    **四、使用JPA实现动态切换** 1. **Repository接口**:创建带有特定数据源注解的Repository接口,例如`@RepositoryDataSource("secondary")`。 2. **Service层**:在Service层中注入Repository接口,Spring会根据...

    13_JPA详解_JPA中的多对多双向关联实体定义与注解设置.zip

    本资料“13_JPA详解_JPA中的多对多双向关联实体定义与注解设置”专注于讲解JPA如何处理多对多双向关联关系,这是数据库设计中常见的一种复杂关联类型。下面我们将详细探讨这一主题。 首先,我们需要理解多对多关联...

    jpa--9.单向多对一

    在Java代码中,我们可以通过以下方式实现单向多对一的映射: 1. **实体定义**: - 在"多"端实体(Employee)中,我们需要添加一个对"一"端实体(Department)的引用。这通常是一个`@ManyToOne`注解的字段。 - ...

    JPA详解视频教程 第10讲 JPA中的一对多双向关联与级联操作.avi

    JPA用于整合现有的ORM技术,可以简化现有Java EE和Java SE应用对象持久化的开发工作,实现ORM的统一。JPA详解视频教程 第10讲 JPA中的一对多双向关联与级联操作.avi

    jpa1.0中文手册

    JPA规范的主要作用是将Java对象映射到关系数据库表中,并提供了一组API来对这些对象执行CRUD(创建、读取、更新、删除)操作。JPA的目的是让开发者能够更简单地编写与数据库交互的代码,同时减少数据库操作的复杂性...

    jpa实现数据库操作

    以上内容涵盖了JPA实现数据库操作的基础知识,随着项目的深入,你可能需要学习更多关于Spring与JPA集成的内容,包括Spring Boot、Spring Data JPA、事务管理、分页查询、自定义查询方法等,这些都是构建高效、可维护...

Global site tag (gtag.js) - Google Analytics