您的位置:首页 > 其它

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

2012-03-11 15:30 363 查看
Student.java

package cn.itcast.bean;

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.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       //id作为实体标识符   并且采用数据库的id自增长方式生成主键值
public Integer getId() {
return id;
}

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

@Column(length = 10, nullable = false)
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;
}
/*
假如不对关联表里的字段做任何设定,那么表里面的字段默认由JPA的实现产品来帮我们自动生成。
inverseJoinColumns:inverse中文是反转的意思,但是觉得太恶心了,在JPA里,可以理解为被维护端
inverseJoinColumns被维护端外键的定义
@JoinColumn:外键,中间表哪个外键名称跟teacher表的主键关联
joinColumns:关系维护端的定义
*/

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


Teacher.java

package cn.itcast.bean;

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

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

@Id @GeneratedValue       //id作为实体标识符   并且采用数据库的id自增长方式生成主键值
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}

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

@ManyToMany(cascade=CascadeType.REFRESH,mappedBy="teachers")
public Set<Student> getStudents() {
return students;
}
/*
cascade:
CascadeType.PERSIST:级联保存不要,学生没来之前,老师就已经在了
CascadeType.MERGE:级联更新不要,把学生的信息改了,没必要修改相应的老师的信息,压根就没这业务需求
CascadeType.REMOVE:级联删除更不要,如果双方都设了级联删除,加入删除学生,会删除相应的老师,被删除的老师又
跟学生发生千丝万缕的关系,又把一批学生删掉.....没完没了...最终的结果可能是数据里面所有的记录都被清掉
所以在多对多关系中,级联删除通常是用不上的
这里只需设置级联涮新CascadeType.PERSIST就可以了,事实上refresh方法也很少使用
mappedBy: 通过这个属性来说明老师是关系被维护端
fetch: 加载行为默认是延迟加载(懒加载),凭Many。 这里不需要设置
*/

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


ManyToManyTest.java

package junit.test;

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

import org.junit.BeforeClass;
import org.junit.Test;

public class ManyToManyTest {

@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test
public void save() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast");
factory.close();
}

}


双向多对多关系是一种对等关系,既然是对等关系,也就是说我们可以人为决定谁是关系维护端,谁是关系被维护端,这里选学生做关系维护端。那么以后就只能通过学生来维护老师跟学生的关系。

假设:
老师A id是1
学生B id是1
那通过什么东西把他们的关系确立起来呢?采用什么来存放他们的关联关系呢?是中间表(关联表)。

学生A和老师B建立起关系,首先要找到关系维护端,是学生,就要通过学生这个关系维护端,学生A.getTeachers().add(Teacher);这样就能把老师跟学生的关系确立起来了。确立起来后,反应在中间表里面就是insert into...一条语句
如果学生A要把老师B开掉,那就要解除关系,也是通过关系维护端学生A,反映在面向对象的操作就是 学生A.getTeachers().remove(Teacher);执行这句代码的时候,在底层JDBC它会对中间表做delete from...语句的操作。
我们都是通过关系维护端来进行操作的,以后在双向关系中一定要找准谁是关系维护端,谁是关系被维护端

@JoinTable的注解有:看图,

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: