一对多关联关系映射(one to many+双向)(见教程23)
hihernate一对多关联映射(双向Classes<----->Student)
一对多双向关联映射:
* 在一一端的集合上使用<key>,在对方表中加入一个外键指向一一端
* 在多一端采用<many-to-one>
注意:<key>标签指定的外键字段必须和<many-to-one>指定的外键字段一致,否则引用字段的错误
如果在”一“一端维护一对多关联关系,hibernate会发出多余的udpate语句,对classid为空这个问题也是个问题,所以我们一般在多
的一端来维护关联关系,这样就不会发出多于的update语句
关于inverse属性:
inverse主要用在一对多和多对多双向关联上,inverse可以被设置到集合标签<set>上,
默认inverse为false,所以我们可以从”一“一端和”多“一端维护关联关系,
如果设置成inverse为true,则我们只能从多一端来维护关联关系
注意:inverse属性,只影响数据的存储,也就是持久化
inverse和cascade
* inverse是关联关系的控制方向
* cascade操作上的连锁反应
我们还是以班级和学生为例来说明这个问题:
第一步建立班级和学生的实体类:
班级实体类为:
public class Classes {
private int id;
private String name;
private Set students; //持有学生类的集合
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getStudents() {
return students;
}
public void setStudents(Set students) {
this.students = students;
}
}
学生的实体类:
public class Student {
private int id;
private String name;
private Classes classes;//持有班级的引用
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
}
}
第二步:写实体类的映射文件:
class的映射文件是:
<hibernate-mapping package="com.bjsxt.hibernate">
<class name="Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students" inverse="true" cascade="all">//设置inverse属性,inverse默认的值为false,是还允许在一的一端来维护这个关系
若设为true,作用是使一的一端失效,让多的一端来维护,目的是为了避免多于发出update和classid为空时存不进去的错误。这样不论采用什么方式存,都会使用多的一端来维护
<key column="classesid"/>
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>
student段的映射文件是:
<hibernate-mapping>
<class name="com.bjsxt.hibernate.Student" table="t_student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="classes" column="classesid"/>//这个字段的名字必须和那边的key中的字段名字一样,原因见教程23.这说不清楚
</class>
</hibernate-mapping>
第三步写hibernate的配置文件:
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_one2many_1</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">bjsxt</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.show_sql">true</property>
<mapping resource="com/bjsxt/hibernate/Classes.hbm.xml"/>
<mapping resource="com/bjsxt/hibernate/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
第四步写测试代码:
public class One2ManyTest extends TestCase {
public void testSave2() {//在多的一端存
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Classes classes = new Classes();
classes.setName("尚学堂");
session.save(classes);
Student student1 = new Student();
student1.setName("10");
student1.setClasses(classes);
session.save(student1);
Student student2 = new Student();
student2.setName("祖儿");
student2.setClasses(classes);
session.save(student2);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testSave3() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Classes classes = new Classes();
classes.setName("尚学堂");
Student student1 = new Student();
student1.setName("10");
student1.setClasses(classes);
Student student2 = new Student();
student2.setName("祖儿");
student2.setClasses(classes);
Set students = new HashSet();
students.add(student1);
students.add(student2);
classes.setStudents(students);
//可以正确保存
session.save(classes);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
public void testLoad2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Student student = (Student)session.load(Student.class, 1);
System.out.println("student.name=" + student.getName());
System.out.println("student.classes.name=" + student.getClasses().getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
}
来源:https://www.cnblogs.com/liuyang-1037/archive/2009/06/03/1495744.html