EJB3中多对多映射实例讲解

来源:互联网 发布:网络推广代理协议 编辑:程序博客网 时间:2024/06/03 21:37

 学生和老师就是多对多的关系。一个学生有多个老师,一个老师教多个学生。多对多映射采取中间表连接的映射
策略,建立的中间表将分别引入两边的主键作为外键。EJB3 对于中间表的元数据提供了可配置的方式,用户可
以自定义中间表的表名,列名。
下面就以学生和老师为例介绍多对多关系的实体Bean 开发
需要映射的数据库表
student
字段名称  字段类型   属性描述
studentid (主键) Int(11) not null 学生ID
studentName varchar(32) not null 学生姓名
teacher
字段名称字段类型属性描述
teacherid (主键) Int(11) not null 教师ID
teacherName varchar(32) not null 教师姓名
中间表teacher_student
字段名称字段类型属性描述
Student_ID Int(11) not null 是student 表studentid 列的
外键
Teacher_ID Int(11) not null 是teacher 表teacherid 列的
外键

Student.java
package com.foshanshop.ejb3.bean;
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;
@SuppressWarnings("serial")
@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) {
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) {
StudentName = studentName;
}
@ManyToMany(mappedBy = "students")
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
}

@ManyToMany 注释表示Student 是多对多关系的一边,mappedBy 属性定义了Student 为双向关系的维护端
(owning side)。
Teacher.java
package com.foshanshop.ejb3.bean;
import java.io.Serializable;
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.Id;

import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
@SuppressWarnings("serial")
@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) {
TeacherName = teacherName;
}
@Id
@GeneratedValue
public Integer getTeacherid() {
return teacherid;
}
public void setTeacherid(Integer teacherid) {
this.teacherid = teacherid;
}
@Column(nullable=false, length=32)
public String getTeacherName() {
return TeacherName;
}
public void setTeacherName(String teacherName) {
TeacherName = teacherName;
}
@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinTable(name = "Teacher_Student",
joinColumns = {@JoinColumn(name = "Teacher_ID", referencedColumnName = "teacherid")},
inverseJoinColumns = {@JoinColumn(name = "Student_ID", referencedColumnName =
"studentid")})
public Set<Student> getStudents() {
return students;
}

public void setStudents(Set<Student> students) {
this.students = students;
}
public void addStudent(Student student) {
if (!this.students.contains(student)) {
this.students.add(student);
}
}
public void removeStudent(Student student) {
this.students.remove(student);
}
}

@ManyToMany 注释表示Teacher 是多对多关系的一端。@JoinTable 描述了多对多关系的数据表关系。name 属
性指定中间表名称,joinColumns 定义中间表与Teacher 表的外键关系。上面的代码中,中间表Teacher_Student
的Teacher_ID 列是Teacher 表的主键列对应的外键列,inverseJoinColumns 属性定义了中间表与另外一端(Student)
的外键关系。
为了使用上面的实体Bean,我们定义一个Session Bean 作为他的使用者。下面是Session Bean 的业务接口,他定
义了三个业务方法insertTeacher,getTeacherByID,和getStudentByID, 三个方法的业务功能是:
insertTeacher 添加一个教师(带学生)进数据库
getTeacherByID 获取指定编号的教师
getStudentByID 获取指定编号的学生
下面是Session Bean 的业务接口及实现类
TeacherDAO.java
package com.foshanshop.ejb3;
import com.foshanshop.ejb3.bean.Student;
import com.foshanshop.ejb3.bean.Teacher;
public interface TeacherDAO {
public void insertTeacher(String name, String[] studentnames);
public Teacher getTeacherByID(Integer teacherid);
public Student getStudentByID(Integer studentid);
}
TeacherDAOBean.java
package com.foshanshop.ejb3.impl;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.foshanshop.ejb3.TeacherDAO;
import com.foshanshop.ejb3.bean.Student;

import com.foshanshop.ejb3.bean.Teacher;
@Stateless
@Remote ({TeacherDAO.class})
public class TeacherDAOBean implements TeacherDAO {
@PersistenceContext
protected EntityManager em;
public void insertTeacher(String name, String[] studentnames) {
Teacher teacher = new Teacher(name);
if (studentnames!=null){
for(int i=0;i<studentnames.length; i++){
teacher.addStudent(new Student(studentnames[i]));
}
}
em.persist(teacher);
}
public Teacher getTeacherByID(Integer teacherid) {
Teacher teacher= em.find(Teacher.class, teacherid);
if (teacher!=null) teacher.getStudents().size();
return teacher;
}
public Student getStudentByID(Integer studentid) {
Student student= em.find(Student.class, studentid);
if (student!=null) student.getTeachers().size();
return student;
}
}
下面是Session Bean 的JSP 客户端代码:
ManyToManyTest.jsp
<%@ page contentType="text/html; charset=GBK"%>
<%@ page import="com.foshanshop.ejb3.TeacherDAO,
com.foshanshop.ejb3.bean.*,
javax.naming.*,
java.util.*"%>
<%
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 ctx = new InitialContext(props);
try {
TeacherDAO teacherdao = (TeacherDAO) ctx.lookup("TeacherDAOBean/remote");
teacherdao.insertTeacher("李老师",new String[]{"张小红","朱小光","龚利"});
Teacher teacher = teacherdao.getTeacherByID(new Integer(1));
if (teacher!=null){
out.println("======= 获取编号为1的老师姓名:"+ teacher.getTeacherName() +"
======<br>");
Iterator iterator = teacher.getStudents().iterator();
while (iterator.hasNext()){
Student student = (Student) iterator.next();
out.println("&nbsp;&nbsp;他的学生:"+ student.getStudentName() +"<br>");
}
}else{
out.println("没有找到编号为1的老师<br>");
}
Student student = teacherdao.getStudentByID(new Integer(1));
if (student!=null){
out.println("======= 获取编号为1的学生姓名:"+ student.getStudentName() +"
======<br>");
Iterator iterator = student.getTeachers().iterator();
while (iterator.hasNext()){
Teacher tc = (Teacher) iterator.next();
out.println("&nbsp;&nbsp;他的老师:"+ tc.getTeacherName() +"<br>");
}
}else{
out.println("没有找到编号为1的学生<br>");
}
} catch (Exception e) {
out.println(e.getMessage());
}
%>

原创粉丝点击