隨筆 - 1  文章 - 1  trackbacks - 0
          <2007年4月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(1)

          隨筆檔案

          文章檔案

          搜索

          •  

          最新評(píng)論

          以前在使用hibernate的時(shí)候,對(duì)“多對(duì)多”關(guān)聯(lián)產(chǎn)生的關(guān)聯(lián)表中數(shù)據(jù)修改起來(lái)很費(fèi)盡,寫這篇文章的目的是針對(duì)雙向關(guān)聯(lián)的多對(duì)多關(guān)系的關(guān)系表數(shù)據(jù)進(jìn)行方便的增刪的操作。如果各位高人已經(jīng)有了更好的方法,請(qǐng)不吝賜教。
          首先,我們定義兩個(gè)實(shí)體。
          Teacher和Student。它們是雙向的多對(duì)多關(guān)系,Teacher是關(guān)系的維護(hù)端,Student是關(guān)系的被維護(hù)端。代碼如下:

          Teacher實(shí)體:
          package com.wish.test.model;

          import java.util.HashMap;
          import java.util.Map;

          import javax.persistence.CascadeType;
          import javax.persistence.Column;
          import javax.persistence.Entity;
          import javax.persistence.Id;
          import javax.persistence.ManyToMany;
          import javax.persistence.Table;

          @Entity
          @Table(name = "t_teacher")
          public class Teacher implements java.io.Serializable
          {
              /**
              *
              */
              private static final long serialVersionUID = -8291865074665564287L;

              @Id
              @Column(name = "TeacherCode", length = 50)
              private String teacherCode;
             
              @Column(name = "TeacherName", length = 50)
              private String teacherName;
             
              @ManyToMany(mappedBy = "teachers", cascade = CascadeType.ALL)
              private Map<String,Student> students = new HashMap<String,Student>();

              public String getTeacherCode()
              {
                  return teacherCode;
              }

              public void setTeacherCode(String teacherCode)
              {
                  this.teacherCode = teacherCode;
              }

              public String getTeacherName()
              {
                  return teacherName;
              }

              public void setTeacherName(String teacherName)
              {
                  this.teacherName = teacherName;
              }

              public Map<String,Student> getStudents()
              {
                  return students;
              }

              public void setStudents(Map<String,Student> students)
              {
                  this.students = students;
              }
             
              public void addStudent(Student student)
              {
                  if(!students.containsKey(student.getStudentCode()))
                  {
                      students.put(student.getStudentCode(), student);
                  }
              }
             
              public void removeStudent(Student student)
              {
                  if(students.containsKey(student.getStudentCode()))
                  {
                      students.remove(student.getStudentCode());
                      System.out.println("remove student:" + student.getStudentName());
                  }
              }
          }

          Student實(shí)體:
          package com.wish.test.model;

          import java.util.HashMap;
          import java.util.Map;

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

          @Entity
          @Table(name = "t_student")
          public class Student implements java.io.Serializable
          {
              /**
              *
              */
              private static final long serialVersionUID = 9088096011898259042L;

              @Id
              @Column(name = "StudentCode", length = 50)
              private String studentCode;

              @Column(name = "StudentName", length = 50)
              private String studentName;

              @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
              @JoinTable(name = "t_student_teacher",
                      joinColumns = { @JoinColumn(name = "StudentCode", referencedColumnName = "studentCode") },
                      inverseJoinColumns = { @JoinColumn(name = "TeacherCode", referencedColumnName = "teacherCode") })
              private Map<String,Teacher> teachers = new HashMap<String,Teacher>();

              public String getStudentCode()
              {
                  return studentCode;
              }

              public void setStudentCode(String studentCode)
              {
                  this.studentCode = studentCode;
              }

              public String getStudentName()
              {
                  return studentName;
              }

              public void setStudentName(String studentName)
              {
                  this.studentName = studentName;
              }

              public Map<String,Teacher> getTeachers()
              {
                  return teachers;
              }

              public void setTeachers(Map<String,Teacher> teachers)
              {
                  this.teachers = teachers;
              }

              public void addTeacher(Teacher teacher)
              {
                  if(!teachers.containsKey(teacher.getTeacherCode()))
                  {
                      this.teachers.put(teacher.getTeacherCode(), teacher);
                  }
              }
             
              public void removeTeacher(Teacher teacher)
              {
                  if(teachers.containsKey(teacher.getTeacherCode()))
                  {
                      teachers.remove(teacher.getTeacherCode());
                      System.out.println("remove teacher:" + teacher.getTeacherName());
                  }
              }
          }
          大家注意到Teacher和Student兩個(gè)實(shí)體中都包含了添加和刪除學(xué)生(教師)的方法:addStudent和removeStudent(addTeacher和removeTeacher),我們將用它們來(lái)進(jìn)行對(duì)管理表數(shù)據(jù)的添加和修改操作。
          第二,我們定義dao層。
          IStudentDao和ITeacherDao,代碼如下:
          IStudentDao
          package com.wish.test.dao;

          import com.wish.test.model.Student;

          public interface IStudentDao
          {
              public void insertStudent(Student student) throws RuntimeException;
             
              public void updateStudent(Student student) throws RuntimeException;
             
              public void deleteStudent(String studentCode) throws RuntimeException;
             
              public Student getStudent(String studentCode) throws RuntimeException;
             
              public Student loadTeachers(Student student) throws RuntimeException;
          }

          ITeacherDao
          package com.wish.test.dao;

          import com.wish.test.model.Teacher;

          public interface ITeacherDao
          {
              public void insertTeacher(Teacher teacher) throws RuntimeException;
             
              public void updateTeacher(Teacher teacher) throws RuntimeException;
             
              public void deleteTeacher(String teacherCode) throws RuntimeException;
             
              public Teacher getTeacher(String teacherCode) throws RuntimeException;
             
              public Teacher loadStudents(Teacher teacher) throws RuntimeException;
          }
          它們的實(shí)現(xiàn)如下:
          StudentDao
          package com.wish.test.dao.impl;

          import javax.persistence.EntityManager;
          import javax.persistence.PersistenceContext;

          import com.wish.test.dao.IStudentDao;
          import com.wish.test.model.Student;

          public class StudentDao implements IStudentDao
          {
              @PersistenceContext
              private EntityManager em;

              @Override
              public void insertStudent(Student student) throws RuntimeException
              {
                  em.persist(student);
              }

              @Override
              public void deleteStudent(String studentCode) throws RuntimeException
              {
                  em.remove(em.find(Student.class, studentCode));
              }

              @Override
              public void updateStudent(Student student) throws RuntimeException
              {
                  em.merge(student);
              }

              @Override
              public Student getStudent(String studentCode) throws RuntimeException
              {
                  return em.find(Student.class, studentCode);
              }

              @Override
              public Student loadTeachers(Student student) throws RuntimeException
              {
                  Student tempStudent = em.find(Student.class, student.getStudentCode());
                  if(tempStudent != null)
                  {
                      tempStudent.getTeachers().size();
                  }
                  return tempStudent;
              }

          }

          TeacherDao
          package com.wish.test.dao.impl;

          import javax.persistence.EntityManager;
          import javax.persistence.PersistenceContext;

          import com.wish.test.dao.ITeacherDao;
          import com.wish.test.model.Teacher;

          public class TeacherDao implements ITeacherDao
          {
              @PersistenceContext
              private EntityManager em;

              @Override
              public void insertTeacher(Teacher teacher) throws RuntimeException
              {
                  em.persist(teacher);
              }

              @Override
              public void deleteTeacher(String teacherCode) throws RuntimeException
              {
                  em.remove(em.find(Teacher.class, teacherCode));
              }

              @Override
              public void updateTeacher(Teacher teacher) throws RuntimeException
              {
                  em.merge(teacher);
              }

              @Override
              public Teacher getTeacher(String teacherCode) throws RuntimeException
              {
                  return em.find(Teacher.class, teacherCode);
              }

              @Override
              public Teacher loadStudents(Teacher teacher) throws RuntimeException
              {
                  Teacher tempTeacher = em.find(Teacher.class, teacher.getTeacherCode());
                  if(tempTeacher != null)
                  {
                      tempTeacher.getStudents().size();
                  }
                  return tempTeacher;
              }

          }

          第三,我們來(lái)定義Service層。
          ITestService
          package com.wish.test.service;

          import com.wish.test.model.Student;
          import com.wish.test.model.Teacher;

          public interface ITestService
          {
              public void addStudent(Student student) throws RuntimeException;
             
              public void modifyStudent(Student student) throws RuntimeException;
             
              public void removeStudent(String studentCode) throws RuntimeException;
             
              public void addTeacher(Teacher teacher) throws RuntimeException;
             
              public void modifyTeacher(Teacher teacher) throws RuntimeException;
             
              public void removeTeacher(String teacherCode) throws RuntimeException;
             
              public Student getStudent(String studentCode) throws RuntimeException;
             
              public Teacher getTeacher(String teacherCode) throws RuntimeException;
             
              public Teacher loadStudents(Teacher teacher) throws RuntimeException;
             
              public Student loadTeachers(Student student) throws RuntimeException;
          }
          其實(shí)現(xiàn)如下:
          TestService
          package com.wish.test.service.impl;

          import org.springframework.transaction.annotation.Transactional;

          import com.wish.test.dao.IStudentDao;
          import com.wish.test.dao.ITeacherDao;
          import com.wish.test.model.Student;
          import com.wish.test.model.Teacher;
          import com.wish.test.service.ITestService;

          public class TestService implements ITestService
          {
              IStudentDao studentDao = null;
              ITeacherDao teacherDao = null;
             
              public TestService(IStudentDao studentDao, ITeacherDao teacherDao)
              {
                  this.studentDao = studentDao;
                  this.teacherDao = teacherDao;
              }

              @Override
              @Transactional(readOnly = false)
              public void addStudent(Student student) throws RuntimeException
              {
                  studentDao.insertStudent(student);
              }

              @Override
              @Transactional(readOnly = false)
              public void addTeacher(Teacher teacher) throws RuntimeException
              {
                  teacherDao.insertTeacher(teacher);
              }

              @Override
              @Transactional(readOnly = false)
              public void removeStudent(String studentCode) throws RuntimeException
              {
                  studentDao.deleteStudent(studentCode);
              }

              @Override
              @Transactional(readOnly = false)
              public void removeTeacher(String teacherCode) throws RuntimeException
              {
                  teacherDao.deleteTeacher(teacherCode);
              }

              @Override
              @Transactional(readOnly = false)
              public void modifyStudent(Student student) throws RuntimeException
              {
                  studentDao.updateStudent(student);
              }

              @Override
              @Transactional(readOnly = false)
              public void modifyTeacher(Teacher teacher) throws RuntimeException
              {
                  teacherDao.updateTeacher(teacher);
              }

              @Override
              @Transactional(readOnly = true)
              public Student getStudent(String studentCode) throws RuntimeException
              {
                  return studentDao.getStudent(studentCode);
              }

              @Override
              @Transactional(readOnly = true)
              public Teacher getTeacher(String teacherCode) throws RuntimeException
              {
                  return teacherDao.getTeacher(teacherCode);
              }

              @Override
              @Transactional(readOnly = true)
              public Teacher loadStudents(Teacher teacher) throws RuntimeException
              {
                  return teacherDao.loadStudents(teacher);
              }

              @Override
              @Transactional(readOnly = true)
              public Student loadTeachers(Student student) throws RuntimeException
              {
                  return studentDao.loadTeachers(student);
              }

          }

          第四,我們來(lái)定義調(diào)用service層的javabean,TestManage。
          代碼如下:
          package com.wish.test.bean;

          import org.apache.log4j.Logger;

          import com.wish.spring.tools.SpringBeanController;
          import com.wish.test.model.Student;
          import com.wish.test.model.Teacher;
          import com.wish.test.service.ITestService;

          public class TestManage
          {
              private ITestService testService = (ITestService)SpringBeanController.getBean("testService");
             
              private static Logger log = Logger.getLogger(TestManage.class);
             
              public boolean addStudent(Student student)
              {
                  try
                  {
                      testService.addStudent(student);
                      return true;
                  }
                  catch (RuntimeException e)
                  {
                      log.error(e.toString());
                      return false;
                  }
              }
             
              public boolean modifyStudent(Student student)
              {
                  try
                  {
                      testService.modifyStudent(student);
                      return true;
                  }
                  catch (RuntimeException e)
                  {
                      log.error(e.toString());
                      return false;
                  }
              }
             
              public boolean removeStudent(String studentCode)
              {
                  try
                  {
                      testService.removeStudent(studentCode);
                      return true;
                  }
                  catch (RuntimeException e)
                  {
                      log.error(e.toString());
                      return false;
                  }
              }
             
              public boolean addTeacher(Teacher teacher)
              {
                  try
                  {
                      testService.addTeacher(teacher);
                      return true;
                  }
                  catch (RuntimeException e)
                  {
                      log.error(e.toString());
                      return false;
                  }
              }
             
              public boolean modifyTeacher(Teacher teacher)
              {
                  try
                  {
                      testService.modifyTeacher(teacher);
                      return true;
                  }
                  catch (RuntimeException e)
                  {
                      log.error(e.toString());
                      return false;
                  }
              }
             
              public boolean removeTeacher(String teacherCode)
              {
                  try
                  {
                      testService.removeTeacher(teacherCode);
                      return true;
                  }
                  catch (RuntimeException e)
                  {
                      log.error(e.toString());
                      return false;
                  }
              }
             
              public Student getStudent(String studentCode)
              {
                  try
                  {
                      return testService.getStudent(studentCode);
                  }
                  catch (RuntimeException e)
                  {
                      log.error(e.toString());
                      return null;
                  }
              }
             
              public Teacher getTeacher(String teacherCode)
              {
                  try
                  {
                      return testService.getTeacher(teacherCode);
                  }
                  catch (RuntimeException e)
                  {
                      log.error(e.toString());
                      return null;
                  }
              }
             
              public Teacher loadStudents(Teacher teacher)
              {
                  try
                  {
                      return testService.loadStudents(teacher);
                  }
                  catch (RuntimeException e)
                  {
                      log.error(e.toString());
                      return null;
                  }
              }
             
              public Student loadTeachers(Student student)
              {
                  try
                  {
                      return testService.loadTeachers(student);
                  }
                  catch (RuntimeException e)
                  {
                      log.error(e.toString());
                      return null;
                  }
              }
          }

          最后,我們?cè)贘SP頁(yè)面中調(diào)用javabean中的方法。
          test.jsp,這些方法可以實(shí)現(xiàn)對(duì)雙向多對(duì)多關(guān)聯(lián)表數(shù)據(jù)的單條增刪操作。
          代碼如下:
          <%@ page language="java" contentType="text/html; charset=UTF-8"
              pageEncoding="UTF-8"%>
          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
          <jsp:useBean id="test" class="com.wish.test.bean.TestManage" scope="request"></jsp:useBean>
          <%@page import="com.wish.test.model.Student"%>
          <%@page import="com.wish.test.model.Teacher"%>
          <html xmlns="http://www.w3.org/1999/xhtml">
          <head>
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
          <title></title>
          </head>
          <body>
          <%
              /**********************************************************************************
              * 說(shuō)明:                                                                                         *
              * Student 和 Teacher 為兩個(gè)實(shí)體,為多對(duì)多關(guān)系;                *
              * Teacher 為關(guān)系的維護(hù)端,Student為被維護(hù)端;             *
              * Teacher 與 Student 為級(jí)聯(lián)添加關(guān)系;                          *
              * 在Student存在addTeacher和removeTeacher方法;                 *
              * 在Teacher存在addStudent和removeStudent方法;                    *
              * 兩個(gè)實(shí)體在數(shù)據(jù)庫(kù)中對(duì)應(yīng)的表中各存在10條記錄,無(wú)關(guān)聯(lián)數(shù)據(jù)     *
              ***********************************************************************************/
             
              /* 添加關(guān)聯(lián) */
              /* 從維護(hù)端添加與被維護(hù)端的關(guān)聯(lián)
              Teacher t = test.getTeacher("teacher01");
              Student s1 = test.getStudent("student01");
              Student s2 = test.getStudent("student02");
              t = test.loadStudents(t);
              s1 = test.loadTeachers(s1);
              s2 = test.loadTeachers(s2);
              t.addStudent(s1);
              t.addStudent(s2);
              s1.addTeacher(t);
              s2.addTeacher(t);
              test.modifyTeacher(t);
              */
             
              /* 從被維護(hù)端添加與維護(hù)端的關(guān)聯(lián)
              Student s = test.getStudent("student03");
              Teacher t2 = test.getTeacher("teacher02");
              Teacher t3 = test.getTeacher("teacher03");
              s = test.loadTeachers(s);
              t2 = test.loadStudents(t2);
              t3 = test.loadStudents(t3);
              s.addTeacher(t2);
              s.addTeacher(t3);
              t2.addStudent(s);
              t3.addStudent(s);
              test.modifyStudent(s);
              */
             
              /* 刪除關(guān)聯(lián) */
              /* 從維護(hù)端刪除與被維護(hù)端的關(guān)聯(lián):目前這種對(duì)應(yīng)模式,無(wú)法從維護(hù)端單條刪除與被維護(hù)端的關(guān)聯(lián)
              Teacher t = test.getTeacher("teacher01");
              Student s1 = test.getStudent("student01");
              Student s2 = test.getStudent("student02");
              t = test.loadStudents(t);
              t.removeStudent(s1);
              test.modifyTeacher(t);
              */

             
              /* 從被維護(hù)端刪除與維護(hù)端的關(guān)聯(lián)
              Student s = test.getStudent("student03");
              Teacher t2 = test.getTeacher("teacher02");
              Teacher t3 = test.getTeacher("teacher03");
              s = test.loadTeachers(s);
              s.removeTeacher(t2);
              //s.removeTeacher(t3);
              test.modifyStudent(s);
              */
             
             
              // 直接刪除維護(hù)端實(shí)體,關(guān)聯(lián)刪除了所有被維護(hù)端
              //test.removeTeacher("teacher01");
              // 直接刪除被維護(hù)端實(shí)體,可以刪除與維護(hù)端的關(guān)聯(lián)************
              //test.removeStudent("student11");
             
             
              // 總結(jié):對(duì)于不經(jīng)常變動(dòng)的實(shí)體,在定義其多對(duì)多關(guān)聯(lián)時(shí),盡量將其定義為被維護(hù)端,這樣對(duì)其增加和修改關(guān)聯(lián)時(shí)比較方便
          %>
          </body>
          </html>

          寫的比較基礎(chǔ),請(qǐng)大家批評(píng)指正。
          posted @ 2008-07-26 08:45 licy 閱讀(3846) | 評(píng)論 (1)編輯 收藏
                自己做程序員有快一年的時(shí)間了,其間經(jīng)歷的過(guò)程想必會(huì)對(duì)剛剛?cè)腴T的新手有些借鑒作用,因此準(zhǔn)備通過(guò)這個(gè)博客寫一些淺顯易懂的東西供新手參考,并希望高手給予指導(dǎo)。
                多交流,勤交流。
          posted @ 2007-04-21 15:34 licy 閱讀(150) | 評(píng)論 (0)編輯 收藏
          主站蜘蛛池模板: 旌德县| 龙南县| 广东省| 微山县| 临海市| 惠州市| 古浪县| 蓬莱市| 封丘县| 花莲县| 乌拉特中旗| 红原县| 盐池县| 新干县| 茶陵县| 洱源县| 沧源| 哈巴河县| 武强县| 海晏县| 延长县| 巧家县| 象州县| 邹平县| 奉新县| 石景山区| 福州市| 红河县| 中方县| 延寿县| 阜康市| 遂溪县| 龙井市| 廊坊市| 龙口市| 湖北省| 渭源县| 阿荣旗| 岳阳县| 贞丰县| 西乌珠穆沁旗|