一直认为通过写SQL语句来处理多对多的情况比较复杂,对表关系必须是理解的非常清楚,在学习了Hibernate中的多对多处理后,想想其实多对多也没什么,只不过多了一张表,如果说多了一张表感觉复杂了,Hibernate中我们完全不用去理会他,直接去操作关联实体就可以了,从这点上看,Hibernate为我们做了很多事,确实功不可没。
在有了Hibernate这个帮手后,今天一起看看我们在Hibernate的基础上进行一些操作。
原理分析
我们拿学生和课程为例子来分析,所谓的多对多关系可以这样理解:一个学生要上多门课,同时很多学生上同一门课,从学生的角度出发可以看到他所上的那些课。对于这样一种关系,我们可以表示为:
Hibernate默认是采用第三方表来存储这样多对多关联的数据,我们在操作实体的过程中是不需要知道这张表的,当然我们也可以更换其他策略。
我们使用many-to-many标签来达到多对多的效果:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.tgb.hibernate.Student" table="t_students">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" />
<!-- 这里同样使用set标签来代表集合,可以指定对应的第三方表 -->
<set name="courses" table="t_student_course">
<key column="student_id" />
<!-- 采用many-to-may标签指定关联实体 -->
<many-to-many class="com.tgb.hibernate.Course" column="course_id" />
</set>
</class>
</hibernate-mapping>
对于另一端Course并不知道Student的存在,使用基本映射就可以映射到表。
操作示例
测试程序如下:
public void testSave1() {
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
/**
* ------多端1:课程------
*/
Course course1 = new Course();
course1.setName("语文");
session.save(course1);
Course course2 = new Course();
course2.setName("数学");
session.save(course2);
Course course3 = new Course();
course3.setName("英语");
session.save(course3);
Course course4 = new Course();
course4.setName("自然");
session.save(course4);
/**
* ------多端2:学生------
*/
Student student1 = new Student();
student1.setName("李雷");
//李雷所上的课的集合
Set<Course> s1courses = new HashSet<Course>();
s1courses.add(course1);
s1courses.add(course3);
student1.setCourses(s1courses);
session.save(student1);
Student student2 = new Student();
student2.setName("韩梅梅");
//韩梅梅所上的课的集合
Set<Course> s2courses = new HashSet<Course>();
s2courses.add(course3);
s2courses.add(course4);
student2.setCourses(s2courses);
session.save(student2);
Student student3 = new Student();
student3.setName("Lucy");
//Lucy所上的课的集合
Set<Course> s3courses = new HashSet<Course>();
s3courses.add(course1);
s3courses.add(course3);
student3.setCourses(s3courses);
session.save(student3);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
if (tx != null) {
tx.rollback();
}
} finally {
HibernateUtils.closeSession(session);
}
}
(说明:程序中调用HibernateUtils的代码实现可参考:千山万水之Hibernate(四)——关联映射(多对一))
总结
本篇博客介绍了多对多实体单向关联上的映射原理,大家可以继续思考双向关联的具体配置,无非是在另外一端Course的映射文件上添加类似的Set、many-to-many标签。
在学习和了解了这些内容后,可以看出,Hibernate确实为我们提供了很好的支持,屏蔽掉表之间的复杂关系,让我们集中主要的精力在开发业务需求上,这样的封装支持,使我们的开发提高了效率。
时间: 2024-09-30 20:07:00