该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-05-07
最后修改:2008-11-12
接上篇 hibernate入门使用系列 3-- xml关系映射篇(中)
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) );
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 class="uuid" /> </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" class="org.py.hib.relation.many2many.Teacher" /> </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 class="uuid" /> </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 class="org.py.hib.relation.many2many.Student" column="student_id" /> </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; @Before public 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; } } } } /** * */ @After public void tearDown() throws Exception { factory.close(); } }
从这个例子中可以看出,many-to-many中,需要引入第3张表来表示关系。 附件中有源代码。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-05-08
哎,好东西啊,再次感谢LZ分享,建议LZ在第一个页面做下第2个页面的连接,2连接3,3连接4,这样方便我们查看,只是LZ费心了.
哎,算是找到好东西了,谢啦,收藏.. |
|
返回顶楼 | |
发表时间:2008-05-09
不错,辛苦楼主了:) 很好的入门教程.
|
|
返回顶楼 | |
发表时间:2008-05-10
讲的不错哦。谢谢
|
|
返回顶楼 | |
发表时间:2008-05-10
真正应用中,在many to many 的关系中,真正纯粹作many to many关联的关联表是不多见的。
如,一个社区网站的圈子和成员是一个多对多的关系,可以用一个中间表来记录它们关系,但通常我们还记录与这种关系相关的一些数据。如会员是何时申请加入到圈子的,是否批准,何时批准,会员在圈子中角色,状态等。 |
|
返回顶楼 | |
发表时间:2008-05-16
hantsy 写道 真正应用中,在many to many 的关系中,真正纯粹作many to many关联的关联表是不多见的。
如,一个社区网站的圈子和成员是一个多对多的关系,可以用一个中间表来记录它们关系,但通常我们还记录与这种关系相关的一些数据。如会员是何时申请加入到圈子的,是否批准,何时批准,会员在圈子中角色,状态等。 用户和用户组的关系经常遇到 many to many的! |
|
返回顶楼 | |
发表时间:2008-05-17
本页的代码出错了
Integer num = (Integer) session.createQuery("from Father").list().size(); num = (Integer) session.createQuery("from Child").list().size(); 应该是from Teacher/Student。 第240行的注释也没有改过来。 ----------------- hibernate的例子很好。 |
|
返回顶楼 | |
发表时间:2008-05-25
iceworld4143 写道 本页的代码出错了
Integer num = (Integer) session.createQuery("from Father").list().size(); num = (Integer) session.createQuery("from Child").list().size(); 应该是from Teacher/Student。 第240行的注释也没有改过来。 ----------------- hibernate的例子很好。 谢谢你的提醒.呵呵.因为是在上一个例子中copy的.所以,有地方没有修改过来.十分抱歉. 已经修改过来了. |
|
返回顶楼 | |
发表时间:2008-05-28
我想问下LZ,必须什么都自己写吗
myeclipse自动生成的POJO,HBM.XML不能用吗 是否,简单修改一下,可以使用 |
|
返回顶楼 | |
发表时间:2008-05-28
不知道有没有好的快速的生成办法,反正我以前做的东西设计的好,主外键明确,23表全部hibernate反向工程,就是 money_money的时候麻烦点
哎,真想找个好办法,让myeclipse 自己弄表关系,烦死了 |
|
返回顶楼 | |