多对多的实体关系模型也是很常见的,比如学生和课程的关系。一个学生可以选修多门课程,一个课程可以被多名学生选修。在关系型数据库中对于多对多关联关系的处理一般采用中间表的形式,将多对多的关系转化成两个一对多的关系。
Student类
public class Student implements Serializable { private Integer id; private String name; private Integer age; private Set<Course> courses = new HashSet<Course>(); }
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="rock.lee.bean.Student" table="student" catalog="test"> <id name="id" column="id" type="int"> <generator class="native"></generator> </id> <property name="name" column="name" type="java.lang.String"></property> <property name="age" column="age" type="int"></property> <set name="courses" table="student_course"> <key column="student_id"></key> <many-to-many class="rock.lee.bean.Course" column="course_id"></many-to-many> </set> </class> </hibernate-mapping>
Course类
public class Course implements Serializable { private Integer id; private String name; private Set<Student> students = new HashSet<Student>(); }
Course.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="rock.lee.bean.Course" table="course" catalog="test"> <id name="id" column="id" type="int"> <generator class="native"></generator> </id> <property name="name" column="name" type="java.lang.String"></property> <!-- 设置关系表 --> <set name="students" table="student_course"> <!-- 关系表中的列名 --> <key column="course_id"></key> <!-- 配置关联对象,关联对象在关系表中的列名 --> <many-to-many class="rock.lee.bean.Student" column="student_id"></many-to-many> </set> </class> </hibernate-mapping>
案例一:测试保存
@Test public void testManyToMany01() { Session session = HibernateUtils.openSession(); Transaction transaction = session.beginTransaction(); Student s1 = new Student("小明", 11); Course c1 = new Course("英语"); //建立学生与课程的关系 s1.getCourses().add(c1); c1.getStudents().add(s1); session.save(s1); session.save(c1); transaction.commit(); session.close(); }
由于学生与课程,课程与学生都建立了关系,这种双向关系在保存是都会像中间表中插入数据,会抛出异常
Caused by: java.sql.BatchUpdateException: Duplicate entry '1-1' for key 'PRIMARY' Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1-1' for key 'PRIMARY'
因为中间表主键重复了
@Test public void testManyToMany01() { Session session = HibernateUtils.openSession(); Transaction transaction = session.beginTransaction(); Student s1 = new Student("小明", 11); Course c1 = new Course("英语"); //建立学生与课程的关系 s1.getCourses().add(c1); // c1.getStudents().add(s1); session.save(s1); session.save(c1); transaction.commit(); session.close(); }
建立学生与课程的关系,不建立课程与学生关系
案例二:解除学生和课程之间的关系
mysql> select * from student; +----+------+------+ | id | name | age | +----+------+------+ | 2 | 小明 | 11 | +----+------+------+ 1 row in set (0.00 sec) mysql> select * from course; +----+------+ | id | name | +----+------+ | 2 | 英语 | +----+------+ 1 row in set (0.02 sec) mysql> select * from student_course; +------------+-----------+ | student_id | course_id | +------------+-----------+ | 2 | 2 | +------------+-----------+ 1 row in set (0.00 sec)
解除学生与课程的关系
@Test public void testManyToMany03() { Session session = HibernateUtils.openSession(); Transaction transaction = session.beginTransaction(); Student s1 = (Student) session.get(Student.class, 2); Course c1 = (Course) session.get(Course.class, 2); s1.getCourses().remove(c1); transaction.commit(); session.close(); }
persistent状态的对象只要一方解除关系,会自动删除关系表中的数据
Hibernate: delete from student_course where student_id=?
案例三:删除有选课的学生
mysql> select * from student_course; +------------+-----------+ | student_id | course_id | +------------+-----------+ | 3 | 3 | +------------+-----------+ 1 row in set (0.00 sec)
删除ID为3的学生
@Test public void testManyToMany04() { Session session = HibernateUtils.openSession(); Transaction transaction = session.beginTransaction(); Student s1 = (Student) session.get(Student.class, 3); session.delete(s1); transaction.commit(); session.close(); }
Hibernate会先删除studnet_course表中的数据,在删除student表中的数据
Hibernate: delete from student_course where student_id=? Hibernate: delete from test.student where id=?
在Student.hbm.xml配置casecade,删除学生时,会同时删除中间表中数据和课程数据
相关推荐
NULL 博文链接:https://mvplee.iteye.com/blog/2186453
hiberante4.2.3-part01
hiberante4.2.3-part2
hiberante-4.2.3-part3
hiberante-4.2.3-part4
DAO层中对Hiberante实例,大家交流一下
hiberante3 注解帮助文档hiberante3 注解帮助文档hiberante3 注解帮助文档hiberante3 注解帮助文档hiberante3 注解帮助文档
Hiberante3.jar + API
最新springboot2基础hiberante5完整项目,打包jar,运行jsp,包括后台与前台,拦截器,登录,后台下载就可以使用,注意不是jpa,里面有完整Dao,千万级数据项目分离的代码,为了适合老项目开发特意集成hiberante5....
hibernate 源码 和hibernate配置的html文档。。非常全面的介绍了hibernate配置。分别在src和zh-cn文件中
开发工具:MyEclipse 6....Struts+Spring+Hiberante框架整合的简单登录系统 无需配置任何文件、只需在mysql中创建一个空数据库 如:create database test; 注:mysql数据库用户名:root 密码:root
hiberante查询方式使用详解,有hql,sql,qbc,以及存储过程,hiberante的基础查询
spring整合
Hibernate Tools是一套全新而且完整的面向Hibernate3的工具集合,它包含了Eclipse插件和Ant编译流程。Hibernate Tools是JBoss Tools的核心组件,所以他也是JBoss Developer Studio的一部分
关于hiberante主键的一对一的映射,单向的,实例
Hiberante HTML 帮助文档 Hiberante HTML 帮助文档 Hiberante HTML 帮助文档
Hibernate双向一对一关联映射(XML版)
hibernate5.0.7jar包,主要是jar包,方便大家下载使用。主要是jar包,方便大家下载使用。主要是jar包,方便大家下载使用
NULL 博文链接:https://86asm.iteye.com/blog/493165
Struts2+hiberante+Spring+Extjs+OA办公系统,完整包正常运行