TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
这篇,主要讲的是 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)
);
[/code] 通过模型,创建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;
}
}[/code] 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;
}
}[/code] 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>
[/code] 注意: set中的 table 指向的是数据库中的关联表。 cascade 用的是save-update , 且inverse用的是false,这样的话,当进行修改和保存和删除时,关联表中的记录也会删掉. 如果cascade 用的是 all 那么连同student表中的记录也会被删除掉。 key中的column指的是: 关联表中与Student发生关系的字段。 而many-to-many中的column指的是:关联表中,与class(这里是:org.py.hib.relation.many2many.Teacher)发生关系的字段。 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>
[/code] 注意: 这里的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("
=== 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("
=== 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("
=== 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("
=== 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("
=== 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("
=== 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("
=== 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();
}
}
[/code] 从这个例子中可以看出,many-to-many中,需要引入第3张表来表示关系。
源码下载:http://file.javaxxz.com/2014/11/3/000002781.zip |
|