- 浏览: 50471 次
- 性别:
- 来自: 长沙
最新评论
-
yaojianxiaoyu:
看你貌似不知道怎么弄,
public class BaseD ...
请教关于得到泛型的class -
d_xxm:
clazz = (Class<T>) ((Pa ...
请教关于得到泛型的class -
jiajia11:
其实第二种方法我觉得不是泛型的应用,你把<T>去掉 ...
请教关于得到泛型的class -
feisan:
推荐使用pylibmc
cmemcache不是很稳定
ubuntu9.04编译安装libmemcache1.4.0.rc -
seman18:
assertTrue("check",a= ...
hibernate入门使用系列 1-- 说明篇+试用篇
接上篇 hibernate入门使用系列 3-- xml关系映射篇(中)
开我写的前3篇中,分别讲了one-to-one, one--to-many, many-to-one 。
这篇,主要讲的是 n:n 的关系。即:many-to-many。
我们以老师和学生为例,一个老师可以交很多学生,同样一个学生可以拥有多个老师,所以,他们之间的关系就是n:n的。
实体模型:
从实体模型来看。有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 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张表来表示关系。
附件中有源代码。
评论
stu1.getTeachers().add(teacher1); stu1.getTeachers().add(teacher2); stu2.getTeachers().add(teacher2); teacher1.getStudents().add(stu2);
能否解释下?
相互引用.
1个老实又多个学生.一个学生也可以由多个老师
stu1.getTeachers().add(teacher1); stu1.getTeachers().add(teacher2); stu2.getTeachers().add(teacher2); teacher1.getStudents().add(stu2);
能否解释下?
你所说的"逆向工程"指的是什么?
好像是MYECLIPSE自带的一个功能吧!
你所说的"逆向工程"指的是什么?
myeclipse自动生成的POJO,HBM.XML不能用吗
是否,简单修改一下,可以使用
我这只是一个test。为了大家明白。其实,更多的时候,还是用spring操作hibernate。这方面,一般每个公司都有自己的一套封装的东西,便于快速开发,能让开发人员更好的关注业务逻辑。可以看看springside。封装得不错。
Assert.assertNotNull(teacher1.getId());
Assert.assertNotNull(teacher2.getId());
Assert.assertNotNull(stu1.getId());
Assert.assertNotNull(stu2.getId());
没什么用啊,这样能测试出什么东西来?
一开始,是没有持久化的。所以,没有id。当持久化后,就会有id了。具体的,请google一下hibernate的缓存机制。以后会讲的。但是,最近又一个很重要的东西要做,所以,没有时间写了。
Assert.assertNotNull(teacher1.getId());
Assert.assertNotNull(teacher2.getId());
Assert.assertNotNull(stu1.getId());
Assert.assertNotNull(stu2.getId());
没什么用啊,这样能测试出什么东西来?
哎,真想找个好办法,让myeclipse 自己弄表关系,烦死了
myeclipse自动生成的POJO,HBM.XML不能用吗
是否,简单修改一下,可以使用
Integer num = (Integer) session.createQuery("from Father").list().size();
num = (Integer) session.createQuery("from Child").list().size();
应该是from Teacher/Student。
第240行的注释也没有改过来。
-----------------
hibernate的例子很好。
谢谢你的提醒.呵呵.因为是在上一个例子中copy的.所以,有地方没有修改过来.十分抱歉.
已经修改过来了.
Integer num = (Integer) session.createQuery("from Father").list().size();
num = (Integer) session.createQuery("from Child").list().size();
应该是from Teacher/Student。
第240行的注释也没有改过来。
-----------------
hibernate的例子很好。
如,一个社区网站的圈子和成员是一个多对多的关系,可以用一个中间表来记录它们关系,但通常我们还记录与这种关系相关的一些数据。如会员是何时申请加入到圈子的,是否批准,何时批准,会员在圈子中角色,状态等。
用户和用户组的关系经常遇到 many to many的!
发表评论
-
hibernate入门使用系列 8-- annotation关系映射篇(下)
2008-11-12 17:27 1895终于要说ManyToMany了 场景:Product和Cust ... -
hibernate入门使用系列 7-- annotation关系映射篇(中)
2008-11-12 16:38 1593这次说说OneToMany和ManyToO ... -
hibernate入门使用系列 6-- annotation关系映射篇(上)
2008-11-12 15:55 2523次讲@OneToOne的用法。而且是基于主外键的关联。因为这个 ... -
hibernate入门使用系列 5 -- xml关系映射篇(补充1)
2008-07-18 18:02 1571由于最近一段时间比较忙。一直被手中的项目牵着。所以,也就没有时 ... -
hibernate入门使用系列 3-- xml关系映射篇(中)
2008-05-07 14:40 2639接上篇 hibernate入门使用系列 2-- xml关系映射 ... -
hibernate入门使用系列 2-- xml关系映射篇(上)
2008-05-05 16:20 2634接上篇 hibernate入门使用系列 1-- 说明篇+试用篇 ... -
hibernate入门使用系列 1-- 说明篇+试用篇
2008-05-05 11:09 3680说明篇 写这个 入门使用 系列的文章, 学习笔 ... -
要不要在数据库中建立主外键约束
2008-05-04 12:48 4748今天发现一个问题。一个遗留的系统上,每个表都是独立的, ...
相关推荐
Hibernate是一种ORM框架,全称为 Object_Relative DateBase-Mapping ,在Java对象与关系数据库之间 建立某种映射,以实现直接存取Java对象 ! 为什么要使用Hibernate? 既然Hibernate是关于Java对象和关系数据库...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
主要内容包括Hibernate的基本体系结构、如何使用Java5注解和基于XML的映射文件来表示映射信息,并讨论了HibernateSession对象和HQL的使用。本书结合大量实际代码,力图使读者能够更好地学习并掌握Hibernate的使用。...
12.5 使用Hibernate的工具快速生成映射文件和POJO 12.5.1 使用MiddleGen根据数据库产生映射文件 12.5.2 使用hbm2java根据映射文件产生POJO 12.6 整合Struts、Spring和Hibernate实现用户管理 12.6.1 Struts、Spring和...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
Hibernate 是一个纯 Java 的对象关系映射和持久性框架,它允许您用 XML 配置文件把普通 Java 对象映射到关系数据库表。使用 Hibernate 能够节约大量项目开发时间,因为整个 JDBC 层都由这个框架管理。这意味着您的...
12.5 使用Hibernate的工具快速生成映射文件和POJO 12.5.1 使用MiddleGen根据数据库产生映射文件 12.5.2 使用hbm2java根据映射文件产生POJO 12.6 整合Struts、Spring和Hibernate实现用户管理 12.6.1 Struts、Spring和...
1. Hibernate入门; 2. 体系结构(Architecture); 3. 配置; 4. 持久化类(Persistent Classes); 5. 对象/关系数据库映射基础(Basic O/R Mapping); 6. 集合类(Collections)映射; 7. 关联关系映射; 8. 组件(Component)...
12.5 使用Hibernate的工具快速生成映射文件和POJO 12.5.1 使用MiddleGen根据数据库产生映射文件 12.5.2 使用hbm2java根据映射文件产生POJO 12.6 整合Struts、Spring和Hibernate实现用户管理 12.6.1 Struts、Spring和...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
Hibernate 快速入门的工程包 包括用xml和annotation映射数据表
2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二部分 ...
Hibernate框架介绍以及入门 【二】 Hibernate的常见配置 一、关于XML提示的配置 1、配置hibernate-mapping-3.0.dtd – XML 配置这三个地方 第一个;location 第二个:URL 第三个: 2、配置hibernate-...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...
2. Hibernate入门 2.1. 前言 2.2. 第一部分 - 第一个Hibernate程序 2.2.1. 第一个class 2.2.2. 映射文件 2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. ...
1. Hibernate入门 1.1. 前言 1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第...