Hibernate多对多单向关联和双向关联
程序员文章站
2022-04-22 16:11:03
...
Hibernate关联关系中相对比较特殊的就是多对多关联,多对多关联与一对一关联和一对多关联不同,多对多关联需要另外一张映射表用于保存多对多映射信息。本例介绍多对多单向关联和双向关联。单向关联 :指具有关联关系的实体对象间的加载与访问关系是单向的。即,只有一个实体对象可以加载和访问对方,但对方是看不到另一方的。双向关联:双向关联是指具有关联关系的实体对象间的加载与访问关系是双向的。即,任何一方均可加载和访问另一方。
一、多对多单向关联
1、首先创建一个数据库,一条SQL语句搞定
create database many_to_many;
2、配置hibernate.cfg.xml
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="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql:///many_to_many
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQL5Dialect
</property>
<property name="hibernate.connection.provider_class">
org.hibernate.c3p0.internal.C3P0ConnectionProvider
</property>
<property name="hibernate.current_session_context_class">
thread
</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<mapping resource="com/beans/Course.hbm.xml" />
<mapping resource="com/beans/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
3、创建实体类及其对应的映射文件
Course.java:
public class Course {
private int cid;
private String cname;
}
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 package="com.beans">
<!-- 完成类到表的映射,属性到字段的映射 -->
<class name="Course">
<id name="cid">
<generator class="native" />
</id>
<property name="cname"/>
</class>
</hibernate-mapping>
Student.java:
private int sid;
private String sname;
private Set<Course> courses;
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 package="com.beans">
<!-- 完成类到表的映射,属性到字段的映射 -->
<class name="Student">
<id name="sid">
<generator class="native" />
</id>
<property name="sname"/>
<set name="courses" cascade="save-update" table="middle" inverse="false">
<key column="studentId" /><!-- 指定当前类在中间表对应的外键 -->
<many-to-many class="Course" column="courseId"/><!-- 指定关联类在中间表中对应的外键 -->
</set>
</class>
</hibernate-mapping>
4、编写测试类
@Test
public void test01() {
Session session = HbnUtils.getSession();//HbnUtils为封装好的工具类
try {
session.beginTransaction();//开启事务
Course course1 = new Course("struts2");
Course course2 = new Course("hibernate5");
Course course3 = new Course("spring4");
Course course4 = new Course("mybatis");
Student student1 = new Student("Thanlon");
Student student2 = new Student("Tom");
student1.getCourses().add(course1);
student1.getCourses().add(course2);
student1.getCourses().add(course3);
student1.getCourses().add(course4);
student2.getCourses().add(course1);
student2.getCourses().add(course2);
student2.getCourses().add(course3);
session.save(student1);
session.save(student2);
session.getTransaction().commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
session.getTransaction().rollback();
}
}
测试结果:
课程表:
学生表:
中间表:
二、多对多双向关联
1、接着上面的,可修改Course类如下。
public class Course {
private int cid;
private String cname;
//修改的地方
private Set<Student> students;
}
2、映射文件可做如下修改
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 package="com.beans">
<!-- 完成类到表的映射,属性到字段的映射 -->
<class name="Course">
<id name="cid">
<generator class="native" />
</id>
<property name="cname" />
<set name="students" cascade="save-update" table="middle" inverse="false">
<key column="courseId" /><!-- 指定当前类在中间表对应的外键 -->
<many-to-many class="Student" column="studentId" /><!-- 指定关联类在中间表中对应的外键 -->
</set>
</class>
</hibernate-mapping>
3、接着是修改测试类:
@Test
public void test01() {
Session session = HbnUtils.getSession();
try {
session.beginTransaction();
Student student1 = new Student("Thanlon");
Student student2 = new Student("Tom");
Course course1 = new Course("struts2");
Course course2 = new Course("hibernate5");
Course course3 = new Course("mybatis");
course1.getStudents().add(student1);
course1.getStudents().add(student2);
course2.getStudents().add(student1);
course3.getStudents().add(student2);
session.save(course1);
session.save(course2);
session.save(course3);
session.getTransaction().commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
session.getTransaction().rollback();
}
}
测试结果:
课程表:
学生表
中间表: