Hibernate的双向多对多的关系映射
来源:互联网 发布:靓心阁优化门窗 编辑:程序博客网 时间:2024/06/11 14:54
最近在学习Hibernate的时候,对象关系映射(ORM)特别重要也特别难懂,现在来记录一下学习过程.
多对多的关系在生活中特别常见,比如老师和学生.一个老师有对应多个学生,一个学生可以有好多个老师.现在就以这个为例子进行学习.
一.首先,建表
对多对的关系映射在仅有的两张数据库表中student和teacher是对应不起来的.需要一个中间表student_teacher来建立联系.
studen表 (student_id为主键自增)
teacher表(teacher_id是主键自增)
中间表student_teacher—>student_id和teacher_id是联合主键(不能设置自动递增)
二.创建映射实体类
Student.java
(生成的get.set方法就不写了)
public class Student { private Integer studentId; private String studentName; private Set<Teacher> teachers = new HashSet<>();
Teacher.java
(生成的get.set方法就不写了)
public class Teacher { private Integer teacherId; private String teacherName; private Set<Student> students = new HashSet<>();
三.写对应的映射文件
student.hbm.xml
<hibernate-mapping package="com.qiushiju.model"> <class name="Student" table="student"> <id name="studentId" column="student_id"> <generator class="native"></generator> </id> <property name="studentName" column="student_name" /> <set name="teachers" table="student_teacher" > <key column="student_id" /> <many-to-many class="Teacher" column="teacher_id" /> </set> </class></hibernate-mapping>
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 package="com.qiushiju.model"> <class name="Teacher" table="teacher"> <id name="teacherId" column="teacher_id"> <generator class="native" /> </id> <property name="teacherName" column="teacher_name" /> <set name="students" table="student_teacher" > <key column="teacher_id"/> <many-to-many class="Student" column="student_id"></many-to-many> </set> </class></hibernate-mapping>
四.编写Hibernate的配置文件.把映射文件注入配置文件中
配置文件为hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration> <session-factory> <!-- 数据库的连接信息 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/hibernate2</property> <property name="connection.username">root</property> <property name="connection.password">qqq030053</property> <!-- 数据库方言 --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 是否打印展示SQL语句 --> <property name="show_sql">true</property> <!-- 当前session保存在什么地方 --> <property name="current_session_context_class">thread</property> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> <!-- 注入映射文件--> <mapping resource="M2MStudent.hbm.xml"/> <mapping resource="M2MTeacher.hbm.xml"/> </session-factory></hibernate-configuration>
五.写测试类
先测试添加
public class TestManyToMany { public static void main(String[] args) { //读取cfg.xml文件 Configuration configuration = new Configuration().configure(); //建立sessionFactory SessionFactory factory = configuration.buildSessionFactory(); //取得session Session session = factory.openSession(); session.beginTransaction(); //创建多个老师 Teacher teacher1 = new Teacher(); teacher1.setTeacherName("老师1"); Teacher teacher2 = new Teacher(); teacher2.setTeacherName("老师2"); //创建多个学生 Student student1 = new Student(); student1.setStudentName("学生1"); Student student2 = new Student(); student2.setStudentName("学生2"); //设定关联关系 //为每个老师添加多名学生 teacher1.getStudents().add(student1); teacher1.getStudents().add(student2); teacher2.getStudents().add(student1); teacher2.getStudents().add(student2); //为每个学生配多名老师 student1.getTeachers().add(teacher1); student1.getTeachers().add(teacher2); student2.getTeachers().add(teacher1); student2.getTeachers().add(teacher2); //保存 session.save(teacher1); session.save(teacher2); session.save(student1); session.save(student2); // 提交.-->这一步才是把数据真正提交至数据库中 session.getTransaction().commit();
输出结果为:
异常:
ERROR: Duplicate entry ‘9-9’ for key ‘PRIMARY’
Exception in thread “main” org.hibernate.exception.ConstraintViolationException: could not execute statement
出现异常是因为两个映射文件的inverse都设为默认的false,则会出现(主键重复),导致插入失败;如果两边都设置inverse为true,则Student和Teacher都去维护关联关系,即同时向连接表插入记录,则会导致主键重复插入失败.
解决办法:让其中一方的inverse设为true,让对方去维护关联关系.
[PS:inverse属性:nverse的真正作用就是指定由哪一方来维护之间的关联关系。当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之间的关联关系,设为true就是放弃维护关联关系.让对方维护;cascade属性:级联操作]
比如Teacher.hbm.xml中修改为:
<set name="students" table="student_teacher" cascade="all" inverse="true">
修改后输出结果为:
Hibernate: insert into teacher (teacher_name) values (?)Hibernate: insert into student (student_name) values (?)Hibernate: insert into teacher (teacher_name) values (?)Hibernate: insert into student (student_name) values (?)Hibernate: insert into student_teacher (student_id, teacher_id) values (?, ?)Hibernate: insert into student_teacher (student_id, teacher_id) values (?, ?)Hibernate: insert into student_teacher (student_id, teacher_id) values (?, ?)Hibernate: insert into student_teacher (student_id, teacher_id) values (?, ?)
此时数据库为:
teacher
student_teacher
student
六.测试关联查询
//通过session操作数据库,得到老师对象 Teacher teacher3 = (Teacher) session.get(Teacher.class, 7); //老师信息为 System.out.println("--->"+teacher3.getTeacherName()); //通过老师找到这个老师对应的全部学生集合 Set<Student> students = teacher3.getStudents(); //遍历输出学生 for (Student student : students) { System.out.println(student.getStudentName()); }
输出结果为:
--->老师1学生2学生1
- Hibernate的双向多对多的关系映射
- Hibernate HelloWorld-07 双向多对一的映射关系
- Hibernate双向的一对多关系映射
- 双向多对多关系的映射
- hibernate双向多对一映射关系
- hibernate对象关系映射(一对一,一对多,多对一,多对多的单向,双向映射)
- hibernate对象关系映射( 一对一,一对多,多对一,多对多的单向,双向映射 ——)
- Hibernate的双向关系映射
- Hibernate关联关系配置-----基于连接表的双向一对多/多对一映射配置
- Hibernate的关系映射多对多
- hibernate的映射关系之一对多
- Hibernate双向一对一,一对多,多对多关系映射
- Hibernate关系映射(11)_多对多双向关联
- Hibernate 关系映射 —— 双向多对多
- Hibernate -- 映射多对多双向关联关系
- Hibernate进阶之双向多对多关系映射
- hibernate关系映射--双向多对多@ManyToMany
- Hibernate 双向 多 对 多 对象关系映射 ,测试 crud
- Spring原理分析1---Spring源码环境搭建和Demo
- 【错误解决】Spring JPA的错误及其解决方案
- CPU Cache
- 挖参还能直播?服务“三农”有新法
- orzdba的安装
- Hibernate的双向多对多的关系映射
- linux mysql-5.7.9免编译版安装
- 商城网站制作从原型到设计开发的具体步骤
- CAS单点登录-自定义认证之JDBC(五)
- 1+2+3+4......+n=sum
- ZJOI 2008 树的统计
- Java九九乘法表
- AHOI 2015 猜谜游戏
- Java集合类详解