首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > XML SOAP >

hibernate入门使用系列 4- xml关系映射篇(上)

2012-10-28 
hibernate入门使用系列 4-- xml关系映射篇(下)接上篇 hibernate入门使用系列 3-- xml关系映射篇(中)开我写

hibernate入门使用系列 4-- xml关系映射篇(下)

接上篇 hibernate入门使用系列 3-- xml关系映射篇(中)



开我写的前3篇中,分别讲了one-to-one, one--to-many, many-to-one 。

这篇,主要讲的是 n:n 的关系。即:many-to-many。

我们以老师和学生为例,一个老师可以交很多学生,同样一个学生可以拥有多个老师,所以,他们之间的关系就是n:n的。

实体模型:


hibernate入门使用系列 4- xml关系映射篇(上)
从实体模型来看。有2个对象,但是为了在数据库中表示出2者的n:n的关系,我们还得引入一张表。所以,sql脚本如下:

 use HibernateQuickUse;drop table if exists teacher_student_relation;drop table if exists Teacher;drop table if exists Student;create table Teacher (tid varchar(32) primary key,name varchar(32) not null);create table Student (sid varchar(32) primary key,name varchar(128) not null);create table teacher_student_relation (id integer auto_increment primary key,teacher_id varchar(32) not null,student_id varchar(32) not null,foreign key(teacher_id) references Teacher(tid),foreign key(student_id) references Student(sid));



通过模型,创建java类如下:

Student.java

package org.py.hib.relation.many2many;import java.util.HashSet;import java.util.Set;/** * Student entity. */@SuppressWarnings("serial")public class Student implements java.io.Serializable{private String id;private String name;private Set<Teacher> teachers = new HashSet<Teacher>(0);public Student(){}public String getId(){return this.id;}public void setId(String id){this.id = id;}public String getName(){return this.name;}public void setName(String name){this.name = name;}public Set<Teacher> getTeachers(){return teachers;}public void setTeachers(Set<Teacher> teachers){this.teachers = teachers;}}

?

Teacher.java:

package org.py.hib.relation.many2many;import java.util.HashSet;import java.util.Set;/** * Teacher entity. */@SuppressWarnings("serial")public class Teacher implements java.io.Serializable{private String id;private String name;private Set<Student> students = new HashSet<Student>(0);public Teacher(){}public String getId(){return this.id;}public void setId(String id){this.id = id;}public String getName(){return this.name;}public void setName(String name){this.name = name;}public Set<Student> getStudents(){return students;}public void setStudents(Set<Student> students){this.students = students;}}
?

xml映射文件如下

Student.hbm.xml

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="org.py.hib.relation.many2many.Student"table="student"><id name="id" type="java.lang.String" column="sid" length="32"><generator /></id><property name="name" type="java.lang.String" column="name"length="128" not-null="true" /><set name="teachers" table="teacher_student_relation" cascade="save-update" inverse="false"><key column="student_id" not-null="true" /><many-to-many column="teacher_id"/></set></class></hibernate-mapping>

?注意:

?set中的 table 指向的是数据库中的关联表。

cascade 用的是save-update, 且inverse用的是false,这样的话,当进行修改和保存和删除时,关联表中的记录也会删掉.

如果cascade 用的是 all 那么连同student表中的记录也会被删除掉。

key中的column指的是: 关联表中与Student发生关系的字段。

而many-to-many中的column指的是:关联表中,与class(这里是:org.py.hib.relation.many2many.Teacher)发生关系的字段。

关于inverse,请参考上篇:hibernate入门使用系列 3-- xml关系映射篇(中)

?

?

Teacher.hbm.xml

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="org.py.hib.relation.many2many.Teacher"table="teacher"><id name="id" type="java.lang.String" column="tid"length="32"><generator /></id><property name="name" type="java.lang.String" column="name"length="32" not-null="true" /><set name="students" table="teacher_student_relation" cascade="save-update"inverse="false"><key column="teacher_id" not-null="true" /><many-to-many /></set></class></hibernate-mapping>

?注意:

这里的inverse也采用了false,这样子的话,Teacher和Student都维护关系表中的关系。

?

?

测试类,Many2ManyTest.java

package org.py.hib.relation.many2many;import java.util.Iterator;import java.util.List;import java.util.Set;import junit.framework.Assert;import junit.framework.TestCase;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.junit.After;import org.junit.Before;public class Many2ManyTest extends TestCase{private SessionFactory factory;@Beforepublic void setUp() throws Exception{Configuration conf = new Configuration().configure();factory = conf.buildSessionFactory();}/** * 测试添加 * @throws Exception */public void testSave() throws Exception{System.out.println("\n=== test save ===");Teacher teacher1 = new Teacher();teacher1.setName("teacher_1");Teacher teacher2 = new Teacher();teacher2.setName("teacher_2");Student stu1 = new Student();stu1.setName("student_1");Student stu2 = new Student();stu2.setName("student_2");stu1.getTeachers().add(teacher1);stu1.getTeachers().add(teacher2);stu2.getTeachers().add(teacher2);teacher1.getStudents().add(stu2);Session session = null;Transaction tran = null;try{session = factory.openSession();tran = session.beginTransaction();session.save(stu1);session.save(stu2);tran.commit();Assert.assertNotNull(teacher1.getId());Assert.assertNotNull(teacher2.getId());Assert.assertNotNull(stu1.getId());Assert.assertNotNull(stu2.getId());} catch (Exception ex){tran.rollback();throw ex;} finally{if (session != null){try{session.close();} catch (Exception ex){// nothing to do} finally{if (session != null)session = null;}}}}/** * 测试从Teacher查询 * @throws Exception */@SuppressWarnings("unchecked")public void testFindFromTeacher() throws Exception{System.out.println("\n=== test find from Teacher ===");Session session = null;try{session = factory.openSession();Iterator<Teacher> iter = session.createQuery("from Teacher").iterate();while (iter.hasNext()){Teacher teacher = iter.next();Assert.assertNotNull(teacher.getId());String teacherName = teacher.getName();if ("teacher_1".equals(teacherName)){Set<Student> stus = teacher.getStudents();Assert.assertEquals(stus.size(), 2);for (Student stu : stus){String stuName = stu.getName();Assert.assertNotNull(stu.getId());Assert.assertTrue(stuName.equals("student_1") || stuName.equals("student_2"));}} else if ("teacher_2".equals(teacherName)){Set<Student> stus = teacher.getStudents();Assert.assertEquals(stus.size(), 2);for (Student stu : stus){String stuName = stu.getName();Assert.assertNotNull(stu.getId());Assert.assertTrue(stuName.equals("student_1") || stuName.equals("student_2"));}} else{throw new Exception("teacher name error exception.");}}} catch (Exception ex){throw ex;} finally{if (session != null){try{session.close();} catch (Exception ex){// nothing to do} finally{if (session != null)session = null;}}}}/** * 测试从Student查询 * @throws Exception */@SuppressWarnings("unchecked")public void testFindFromStudent() throws Exception{System.out.println("\n=== test find from Student ===");Session session = null;try{session = factory.openSession();Iterator<Student> iter = session.createQuery("from Student").iterate();while (iter.hasNext()){Student stu = iter.next();Assert.assertNotNull(stu.getId());String stuName = stu.getName();if ("student_1".equals(stuName)){Set<Teacher> teachers = stu.getTeachers();Assert.assertEquals(teachers.size(), 2);for (Teacher teacher : teachers){String tName = teacher.getName();Assert.assertNotNull(teacher.getId());Assert.assertTrue(tName.equals("teacher_1") || tName.equals("teacher_2"));}} else if ("student_2".equals(stuName)){Set<Teacher> teachers = stu.getTeachers();Assert.assertEquals(teachers.size(), 2);for (Teacher teacher : teachers){String tName = teacher.getName();Assert.assertNotNull(teacher.getId());Assert.assertTrue(tName.equals("teacher_1") || tName.equals("teacher_2"));}} else{throw new Exception("student name error exception.");}}} catch (Exception ex){throw ex;} finally{if (session != null){try{session.close();} catch (Exception ex){// nothing to do} finally{if (session != null)session = null;}}}}/** * 测试修改 * @throws Exception */public void testModify() throws Exception{System.out.println("\n=== test modify ===");Session session = null;Transaction tran = null;try{session = factory.openSession();tran = session.beginTransaction();Teacher t1 = (Teacher) session.createQuery("from Teacher t where t.name='teacher_1'").list().get(0);t1.setName("new_teacher_1"); // 修改用户名 = m_name2.(原来用户名= m_name)Set<Student> stus = t1.getStudents();for (Student stu : stus){if (stu.getName().equals("student_1")){stus.remove(stu);break;}}tran.commit();} catch (Exception ex){throw ex;} finally{if (session != null){try{session.close();} catch (Exception ex){// nothing to do} finally{if (session != null)session = null;}}}/* * 修改后再查询 */System.out.println("\n=== test find from Teacher after modify===");try{session = factory.openSession();Iterator<Teacher> iter = session.createQuery("from Teacher").iterate();while (iter.hasNext()){Teacher teacher = iter.next();Assert.assertNotNull(teacher.getId());String teacherName = teacher.getName();if ("new_teacher_1".equals(teacherName)){Set<Student> stus = teacher.getStudents();Assert.assertEquals(stus.size(), 1);for (Student stu : stus){String stuName = stu.getName();Assert.assertNotNull(stu.getId());Assert.assertTrue(stuName.equals("student_2"));}} else if ("teacher_2".equals(teacherName)){Set<Student> stus = teacher.getStudents();Assert.assertEquals(stus.size(), 2);for (Student stu : stus){String stuName = stu.getName();Assert.assertNotNull(stu.getId());Assert.assertTrue(stuName.equals("student_1") || stuName.equals("student_2"));}} else{throw new Exception("teacher name error exception.");}}} catch (Exception ex){throw ex;} finally{if (session != null){try{session.close();} catch (Exception ex){// nothing to do} finally{if (session != null)session = null;}}}}/** * 测试删除 * @throws Exception */public void testDelete() throws Exception{System.out.println("\n=== test delete ===");Session session = null;Transaction tran = null;try{session = factory.openSession();tran = session.beginTransaction();Iterator<Teacher> iter = session.createQuery("from Teacher").iterate();while (iter.hasNext())session.delete(iter.next());tran.commit();Integer count = (Integer) session.createQuery("select count(*) from Teacher").list().get(0);Assert.assertEquals(0, count.intValue());} catch (Exception ex){throw ex;} finally{if (session != null){try{session.close();} catch (Exception ex){// nothing to do} finally{if (session != null)session = null;}}}/* * 删除后再查询 */System.out.println("\n=== test find after delete ===");try{session = factory.openSession();Integer num = (Integer) session.createQuery("from Teacher").list().size();Assert.assertEquals(0, num.intValue());num = (Integer) session.createQuery("from Student").list().size();Assert.assertEquals(0, num.intValue());} catch (Exception ex){throw ex;} finally{if (session != null){try{session.close();} catch (Exception ex){// nothing to do} finally{if (session != null)session = null;}}}}/** *  */@Afterpublic void tearDown() throws Exception{factory.close();}}

?

从这个例子中可以看出,many-to-many中,需要引入第3张表来表示关系。

附件中有源代码。

?

?

stu1.getTeachers().add(teacher1); stu1.getTeachers().add(teacher2); stu2.getTeachers().add(teacher2); teacher1.getStudents().add(stu2);
能否解释下? stu1.getTeachers().add(teacher1); stu1.getTeachers().add(teacher2); stu2.getTeachers().add(teacher2); teacher1.getStudents().add(stu2);
能否解释下?

相互引用.
1个老实又多个学生.一个学生也可以由多个老师
28 楼 only_java 2009-01-06   同时在两个<set>中设置cascade="save-update"是什么意思?更新任何一方的持久化对象时都会级联更新另外一方的对象?

热点排行