欢迎投稿

今日深度:

Hibernate关联关系映射之多对多关联关系,hiberna

Hibernate关联关系映射之多对多关联关系,hibernate多对


本次仍然使用一个示例的方式进行演示,学生与教师之间的关系就是一个典型的多对多关系,一个教师可以有多个学生,同样一个学生也可以有多个教师。在数据库中存储需要一张学生表存储学生信息,一个教师表存储教师信息,为了表示他们之间的关系我们需要一个中间表来表示他们之间的联系。

例如,在教师表中有id,name两个属性,学生表中同样有id,name两个属性。教师表中有两条记录分别是(1,董老师),(2,李老师);学生表中同样有两条(1,张三),(2,李四)。在中间表中有两个字段(teacherId,studentId),这两个字段构成一个联合主键,同时这两个字段又是教师表和学生表的外键,老师和学生进行关联的时候直接插入关联的老师和学生的id在中间表内即可,例如在中间表中插入(1,1)表示董老师与张三进行关联,插入(1,2)表示董老师与李四关联。

下面我们看一下Teacher类和Student类

package entity;

import java.util.HashSet;
import java.util.Set;

public class Teacher {
	private Long id;
	private String name;
	private Set<Student> students = new HashSet<Student>();
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set<Student> getStudents() {
		return students;
	}
	public void setStudents(Set<Student> students) {
		this.students = students;
	}
}
package entity;

import java.util.HashSet;
import java.util.Set;

public class Student {
	private Long id;
	private String name;	
	private Set<Teacher> teachers = new HashSet<Teacher>();
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set<Teacher> getTeachers() {
		return teachers;
	}
	public void setTeachers(Set<Teacher> teachers) {
		this.teachers = teachers;
	}	
}

在POJO类中仍然使用集合表示有多条记录。

下面在看一个他们的映射配置文件

首先看Teacher.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="entity.Teacher" table="Teacher" schema="MYHR">
        <id name="id" type="long">
            <column name="ID"/>
            <generator class="assigned" />
        </id>
        <property name="name" type="string">
            <column name="NAME" not-null="true" />
        </property>
        <!-- students属性,Set集合,表示本类与Student类的多对多关系 -->
        <set name="students" table="teacher_student" inverse="false">
            <key column="teacherId" />
            <many-to-many class="entity.Student" column="studentId"/>
        </set>
    </class>
</hibernate-mapping>

类中的Set类型的属性在映射配置文件中仍然使用<set>标签进行映射,在<set>标签中使用<many-to-many>表示他们之间的关系是多对多。

然后看Student.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="entity.Student" table="Student" schema="MYHR">
        <id name="id" type="long">
            <column name="ID" />
            <generator class="assigned" />
        </id>
        <property name="name" type="string">
            <column name="NAME" not-null="true" />
        </property>
        <!-- teachers属性, Set集合,表示本类与Teacher类的多对多关联关系-->
        <!-- table:是实现多对多映射的中间表 -->
        <!-- key:集合外键(引用当前表主键的那个外键) -->
        <set name="teachers" table="teacher_student">
            <key column="studentId" />
            <many-to-many class="entity.Teacher" column="teacherId"/>
        </set>
    </class>
</hibernate-mapping>

这样,教师和学生之间的多对多关联映射就配置完了,下面看一下测试类。这里使用JUtil进行测试

package test;

import static org.junit.Assert.*;

import java.util.Iterator;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;

import entity.Student;
import entity.Teacher;
import factory.HibernateSessionFactory;

public class Test {

	private Session session = null;
	private Transaction tran = null;

	// 存储对象
	@org.junit.Test
	public void save() {
		session = HibernateSessionFactory.getSession();
		tran = session.beginTransaction();
		try {
			Teacher teacher = new Teacher();
			teacher.setId(1L);
			teacher.setName("董老师");

			Teacher t2 = new Teacher();
			t2.setId(2l);
			t2.setName("李老师");

			Student s1 = new Student();
			s1.setId(1L);
			s1.setName("李四");

			Student s2 = new Student();
			s2.setId(2l);
			s2.setName("张三");

			teacher.getStudents().add(s1);
			teacher.getStudents().add(s2);
			t2.getStudents().add(s1);
			t2.getStudents().add(s2);
			s1.getTeachers().add(teacher);
			s1.getTeachers().add(t2);
			s2.getTeachers().add(teacher);
			s2.getTeachers().add(t2);

			session.save(teacher);
			session.save(t2);
			session.save(s1);
			session.save(s2);

			tran.commit();
		} catch (Exception e) {
			tran.rollback();
		}
	}

	// 获取老师信息
	@org.junit.Test
	public void GetTeacher() {
		session = HibernateSessionFactory.getSession();
		tran = session.beginTransaction();
		try {
			Teacher teacher = (Teacher) session.get(Teacher.class, 1l);
			Set<Student> set = teacher.getStudents();
			System.out.println(teacher.getName() + "的学生是:");
			Iterator<Student> it = set.iterator();
			while (it.hasNext()) {
				Student s = it.next();
				System.out.println(s.getName());
			}
			tran.commit();
		} catch (Exception e) {
			tran.rollback();
		}
	}

	// 解除关联关系
	@org.junit.Test
	public void RemoveRelation() {
		session = HibernateSessionFactory.getSession();
		tran = session.beginTransaction();
		try {
			Student s = (Student) session.get(Student.class, 1l);
			Teacher teacher = (Teacher) session.get(Teacher.class, 1l);
			// 如果Teacher的inverse属性为false可以解除,如果为true不可以解除
			teacher.getStudents().remove(s);
			tran.commit();
		} catch (Exception e) {
			tran.rollback();
		}
	}

	// 删除关联关系
	@org.junit.Test
	public void DeleteRelation() {
		session = HibernateSessionFactory.getSession();
		tran = session.beginTransaction();
		try {
			Teacher teacher = (Teacher) session.get(Teacher.class, 2l);
			// 当teacher的inverse属性为false时,可以将教师信息删除,并且将中间表中相关记录删除
			// 当inverse属性为true时将教师信息删除时抛出异常
			session.delete(teacher);
			tran.commit();
		} catch (Exception e) {
			tran.rollback();
		}
	}
}


 


hibernate一对多映射时,单向关联与双向关联有什不同,哪个好?

<one-to-many> 单向关联就是只使用单方面来维护关系,双向关联就是双方面都要维护关系, 要决定是使用单向的关联还是双向的关联,要取决你的业务要求,如果单向联系能够达到你所需要的业务要求,那肯定就是选择单向的关联(我的建议也是使用单向的关联,使用双向的关联,关系复杂了,容易出现问题)。关联的时候还涉及的就是控制权的问题,在<one-to-many>最好把控制权给与many的那方(控制权就是谁来维护他们之间的关系),
 

hibernate 多对多 利用联合主键 映射一个复杂中间表的双向多对多关联

举个例子:
多对多双向关联
关系举例:老师<-->学生,老师需要知道自己教了哪些学生,学生也知道自己有哪些老师.
数据库:中间表
Annotation:@ManyToMany
XML:<many-to-many>
多对多单向配置只需要在一端进行配置就可以了,双向需要配置两端.
关系模型(Teache多对多Student)
Teacher(id,name,students)多
Set<Student> students=new HashSet<Student>()

Student(id,name,teachers)多
Set<Teacher> teachers = new HashSet<Teacher>();

Annotation配置
在Teacher这一端的students上配置
//如果手动指定生成的中间表的表名和字段名
@ManyToMany
@JoinTable(name="t_s",
joinColumns={@JoinColumn(name="teacher_id")},
inverseJoinColumns={@JoinColumn(name="student_id")}
)
在Student一端的teachers只需要配置
@ManyToMany(mappedBy="students")

XML配置方式:两端配置一样,注意表名和生成的中间表的字段属性名要一致
Teacher那一端配置
<set name="students" table="t_s">
<key column="teacher_id"/>
<many-to-many class="com.xxx.Student" column="student_id"/>
</set>
在Student那一端配置
<set name="teachers" table="t_s">
<key column="student_id"></key>
<many-to-many class="com.xxx.Teacher" column="teacher_id"/>
</set>
生成的表为
create table Student (
id integer not null auto_increment,
name varchar(255),
primary key (id)
)
create table Teacher (
id integer not null auto_increment,
name varchar(255),
primary key (id)
)
create table t_s (//生成的中间表
teacher_id integer not null,
student_id ......余下全文>>
 

www.htsjk.Com true http://www.htsjk.com/shujukunews/3489.html NewsArticle Hibernate关联关系映射之多对多关联关系,hibernate多对 本次仍然使用一个示例的方式进行演示,学生与教师之间的关系就是一个典型的多对多关系,一个教师可以有多个学生,同样一个学...
评论暂时关闭