欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JPA中多对多的实现

程序员文章站 2022-04-24 10:30:52
...
[color=red][size=medium]我是用自己搭建的一个seam工程,去实现JPA中的多对多的关系[/size][/color]
[color=blue]示例背景:
一个学生可以有多个老师,一个老师也可以有多个学生,这是一个我们都知道事实[/color]

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

1.[b][color=red]Student.java类[/color][/b] [b][color=blue]这是关系维护端[/color][/b]

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.[b][color=red]Teacher.java类[/color][/b] [b][color=blue]这是关系被维护端[/color][/b]

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.[b][color=red]Many2ManyTest.java类[/color][/b] [b][color=blue]这是测试方法[/color][/b]

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();
}

}