Hibernate多对多关联会生成一张中间表作为管理关系表
代码结构和使用的jar
Student.java(省略get sert方法)
package com.orange.demo;
import java.util.HashSet;
import java.util.Set;
/**
* 学生实体
*/
public class Student {
private Integer studentId;
private String studentName;
private Set<Teacher> teachers = new HashSet<Teacher>();
}
Teacher.java
package com.orange.demo;
import java.util.HashSet;
import java.util.Set;
/**
* 老师实体
*/
public class Teacher {
private Integer teacherId;
private String teacherName;
private Set<Student> students = new HashSet<Student>();
}
Test.java
package com.orange.demo;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class Test {
private static SessionFactory sessionFactory = null;
static{
Configuration cfg = new Configuration();
cfg.configure("hibernate.cfg.xml"); //在src目录下
sessionFactory = cfg.buildSessionFactory();
}
public static void main(String[] args) {
try {
// save();
delete();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void save() throws Exception {
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Student student1 = new Student();
student1.setStudentName("大橙子同学");
Student student2 = new Student();
student2.setStudentName("二橙子同学");
Teacher teacher1 = new Teacher();
teacher1.setTeacherName("王老师");
Teacher teacher2 = new Teacher();
teacher2.setTeacherName("汪老师");
//第1种:通过学生维护关联关系
//在Student.hbm.xml需要设置inverse=false
//在Teacher.hbm.xml需要设置inverse=true
student1.getTeachers().add(teacher1);
student1.getTeachers().add(teacher2);
student2.getTeachers().add(teacher1);
student2.getTeachers().add(teacher2);
//第2种:通过老师维护关联关系
//在Student.hbm.xml需要设置inverse=true
//在Teacher.hbm.xml需要设置inverse=false
// teacher1.getStudents().add(student1);
// teacher1.getStudents().add(student2);
// teacher2.getStudents().add(student1);
// teacher2.getStudents().add(student2);
session.save(student1);
session.save(student2);
session.save(teacher1);
session.save(teacher2);
tx.commit();
session.close();
}
public static void delete() throws Exception{
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
//Student.hbm.xml inverse=false可以删除学生,并删除关联关系(关联关系表数据被删掉),inverse=true时不能删除,删除时会异常
Student stu = (Student) session.get(Student.class, 1);
session.delete(stu);
tx.commit();
session.close();
}
}
inverse属性用法
Student.hbm.xml和Teacher.hbm.xml 的inverse都设置false表示都来维护关联关系
所以在save方法中添加关联关系选择一种就可以了,如果选择两种会报错
Student.hbm.xml和Teacher.hbm.xml 的inverse都设置true表示都让对方来维护关联关系,但实际上都没有维护
所以在save方法中即使 第1种方法和第2种方法同时使用也没有向关系表插入数据
Student.hbm.xml inverse设置false,Teacher.hbm.xml inverse设置true表示学生来维护关联关系,
在save方法中使用第1种或者第1种和第2种同时使用都能维护关联关系,并且不会报异常,
因为老师端不会维护关联关系,所以这种情况下只用第2种方法是不能维护关联关系。
Student.hbm.xml
<?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 package="com.orange.demo">
<class name="Student" table="t_student">
<id name="studentId" column="studentId">
<generator class="native"></generator>
</id>
<property name="studentName" column="studentName" type="string"></property>
<set name="teachers" table="t_teacher_student" inverse="false">
<key column="studentId"></key>
<many-to-many class="Teacher" column="teacherId"/>
</set>
</class>
</hibernate-mapping>
Teacher.hbm.xml
<?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 package="com.orange.demo">
<class name="Teacher" table="t_teacher">
<id name="teacherId" column="teacherId">
<generator class="native"></generator>
</id>
<property name="teacherName" column="teacherName" type="string"></property>
<set name="students" table="t_teacher_student" inverse="true">
<key column="teacherId"></key>
<many-to-many class="Student" column="studentId"/>
</set>
</class>
</hibernate-mapping>
hibernate.cfg.xml
<!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 name="foo">
<!-- 数据库方言 -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.url">jdbc:mysql://localhost:3306/t1?characterEncoding=UTF-8</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<!-- 在控制台打印SQL,但不能打印建表语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 打印SQL是否格式化 false:不格式化 -->
<property name="hibernate.format_sql">false</property>
<!--自动更新数据库结构 -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="com/orange/demo/Student.hbm.xml"/>
<mapping resource="com/orange/demo/Teacher.hbm.xml"/>
</session-factory>
</hibernate-configuration>