go4it

just do it

实体bean(十四)多对多映射

mappedBy:

1.表明是双向关联

2.在一对多中避免产生中间表,在不使用mappedBy的一方,即多方设外键来与一方关联

3.双向关系中的反向端必须使用@OneToOne、@OneToMany、@ManyToMany注解中的mappedBy元素来引用持有端的关联属性。

   mappedBy元素标注了关系持有者的关系值域或属性;

------------------------------------------------------------------------------------------------------------------------------

student:

package com.persia.jpa.mtm;

import java.io.Serializable;
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;
import javax.persistence.Table;

@Entity
@Table(name="student")
public class Student implements Serializable {
	
	private Integer studentid;
	private String studentName;
	private Set<Teacher> teachers=new HashSet<Teacher>();
	
	public Student(){}
	public Student(String studentName){
		this.studentName=studentName;
	}
	
	@Id
	@GeneratedValue
	public Integer getStudentid() {
		return studentid;
	}
	public void setStudentid(Integer studentid) {
		this.studentid = studentid;
	}
	
	@Column(nullable=false,length=32)
	public String getStudentName() {
		return studentName;
	}
	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}
	
	@ManyToMany(mappedBy="students")
	public Set<Teacher> getTeachers() {
		return teachers;
	}
	public void setTeachers(Set<Teacher> teachers) {
		this.teachers = teachers;
	}
	
	

}
 
teacher:
package com.persia.jpa.mtm;

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

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

@Entity
@Table(name="teacher")
public class Teacher implements Serializable {

	private Integer teacherid;
	private String teacherName;
	private Set<Student> students=new HashSet<Student>();
	
	public Teacher(){}
	public Teacher(String teacherName){
		this.teacherName=teacherName;
	}
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public Integer getTeacherid() {
		return teacherid;
	}
	public void setTeacherid(Integer teacherid) {
		this.teacherid = teacherid;
	}
	public String getTeacherName() {
		return teacherName;
	}
	public void setTeacherName(String teacherName) {
		this.teacherName = teacherName;
	}
	
	@ManyToMany(cascade=CascadeType.PERSIST,fetch=FetchType.LAZY)
	@JoinTable(name="teacher_student",
			//指明本方id关联的列名及引用自哪一列
			   joinColumns={@JoinColumn(name="Teacher_Id",referencedColumnName="teacherid")},
			   inverseJoinColumns={@JoinColumn(name="Student_Id",referencedColumnName="studentid")}
	       //指明关联方id所对应的列名及引用自哪一列

	)
	public Set<Student> getStudents() {
		return students;
	}
	public void setStudents(Set<Student> students) {
		this.students = students;
	}
	
	public void addStudent(Student stu){
		if(!this.students.contains(stu)){
			this.students.add(stu);
		}
	}
	
	public void removeStudent(Student stu){
		this.students.remove(stu);
	}
	
}
 
dao:
package com.persia.jpa.mtm;

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

import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
@Remote({TeacherDAO.class})
public class TeacherDAOBean implements TeacherDAO {
	
	@PersistenceContext
	private EntityManager em;

	public TeacherDAOBean() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public Student getStudentByID(Integer studentid) {
		Student s=em.find(Student.class, studentid);
		if(s!=null) s.getTeachers().size();
		return s;
	}

	@Override
	public Teacher getTeacherByID(Integer teacherid) {
		Teacher t=em.find(Teacher.class, teacherid);
		if(t!=null) t.getStudents().size();
		return t;
	}

	@Override
	public void insertTeacher() {
		Teacher t1=new Teacher();
		t1.setTeacherName("persia");
		Teacher t2=new Teacher();
		t2.setTeacherName("linda");
		
		Student s1=new Student();
		s1.setStudentName("aaa");
		Student s2=new Student();
		s2.setStudentName("bbb");
		
		Set s=new HashSet();
		s.add(s1);
		s.add(s2);
		
		t1.setStudents(s);
		t2.setStudents(s);
		
		em.persist(t1);
		em.persist(t2);

	}

	@Override
	public void removeStudent(Integer studentid) {
		Student stu=em.find(Student.class, studentid);
		Set set=stu.getTeachers();
		Iterator it=set.iterator();
		while(it.hasNext()){
			Teacher t=(Teacher)it.next();
			t.removeStudent(stu);
		}
        stu.setTeachers(null);
        em.remove(stu);
	}

	@Override
	public void removeTeacher(Integer teacherid) {
		Teacher t=em.find(Teacher.class, teacherid);
		em.remove(t);

	}

}
 

注解mappedBy的一方为主动方,就像order和orderItem里面的order,它通过mappedBy来允许被动方来访问它。

删除的时候,如果被动方是延迟加载,则可以直接删除被动方;否则必须逐一删除,将自己从主动方中删除。

在一对多中,可以直接删除mappedBy的一方,而在多对多中,删除mappedBy的一方时必须逐一解除跟另一方的关系。

这里student是主动方,所有删除student的时候,要先把它的teacher在关联表先删除掉(但teacher表本身的数据不删)。

如果cascade=CascadeType.ALL的时候,删除student,则连teacher也删除了。

(不知道这里的主动被动称呼是否得当?)

 

test:

package com.persia.jpa.mtmtest;

import java.util.Iterator;

import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import com.persia.jpa.mtm.Student;
import com.persia.jpa.mtm.Teacher;
import com.persia.jpa.mtm.TeacherDAO;

public class TestMTM {

	/**
	 * @param args
	 * @throws NamingException 
	 */
	public static void main(String[] args) throws NamingException {
		Properties props=new Properties();
	      props.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
	      props.setProperty("java.naming.provider.url","localhost:1099");
	      props.setProperty("java.naming.factory.url.pkgs","org.jboss.naming");
		InitialContext context=new InitialContext(props);
		
		try{
		  TeacherDAO tdao=(TeacherDAO)context.lookup("TeacherDAOBean/remote");
		//  tdao.insertTeacher();
		  Teacher t=tdao.getTeacherByID(new Integer(1));
		  if(t!=null){
			  System.out.println("=====编号为1的老师姓名:"+t.getTeacherName());
			  Iterator it=t.getStudents().iterator();
			  while(it.hasNext()){
				  Student stu=(Student)it.next();
				  System.out.println("他的学生:"+stu.getStudentName());
			  }
		  }else{
			  System.out.println("找不到编号为1的老师的学生");
		  }
		  
		  tdao.removeStudent(new Integer(1));
		
		}catch(Exception e){
			e.printStackTrace();
		}
		

	}

}

 

database:

mysql> select * from student;
+-----------+-------------+
| studentid | studentName |
+-----------+-------------+
|         1 | aaa         |
|         2 | bbb         |
+-----------+-------------+
2 rows in set (0.00 sec)

mysql> select * from teacher;
+-----------+-------------+
| teacherid | teacherName |
+-----------+-------------+
|         1 | persia      |
|         2 | linda       |
+-----------+-------------+
2 rows in set (0.00 sec)

mysql> select * from teacher_student;
+------------+------------+
| Teacher_Id | Student_Id |
+------------+------------+
|          1 |          1 |
|          1 |          2 |
|          2 |          1 |
|          2 |          2 |
+------------+------------+
4 rows in set (0.00 sec)

 

执行删除student 1 之后:(前后对比)

mysql> select * from teacher_student;
+------------+------------+
| Teacher_Id | Student_Id |
+------------+------------+
|          1 |          1 |
|          1 |          2 |
|          2 |          1 |
|          2 |          2 |
+------------+------------+
4 rows in set (0.00 sec)
后:
mysql> select * from teacher_student;
+------------+------------+
| Teacher_Id | Student_Id |
+------------+------------+
|          1 |          2 |
|          2 |          2 |
+------------+------------+
2 rows in set (0.00 sec)
mysql> select * from student;
+-----------+-------------+
| studentid | studentName |
+-----------+-------------+
|         2 | bbb         |
+-----------+-------------+
1 row in set (0.00 sec)

mysql> select * from teacher;
+-----------+-------------+
| teacherid | teacherName |
+-----------+-------------+
|         1 | persia      |
|         2 | linda       |
+-----------+-------------+
2 rows in set (0.00 sec)

 

当删除teacher时:

tdao.removeTeacher(new Integer(1));

 

mysql> select * from teacher;
+-----------+-------------+
| teacherid | teacherName |
+-----------+-------------+
|         2 | linda       |
+-----------+-------------+
1 row in set (0.00 sec)

mysql> select * from student;
+-----------+-------------+
| studentid | studentName |
+-----------+-------------+
|         1 | bbb         |
|         2 | aaa         |
+-----------+-------------+
2 rows in set (0.00 sec)

mysql> select * from teacher_student;
+------------+------------+
| Teacher_Id | Student_Id |
+------------+------------+
|          2 |          1 |
|          2 |          2 |
+------------+------------+
2 rows in set (0.00 sec)

posted on 2009-01-20 18:59  cxccbv  阅读(608)  评论(0)    收藏  举报

导航