您的位置:首页 > 其它

Hibernate双向多对一关系

2016-04-13 10:07 281 查看
在实际中,一个班级对应多个学生,多个学生对应一个班级,相当要同时配置单向的一对多和单向的多对一。

Student类如下:

package com.imooc.entity;

import java.io.Serializable;

public class Student implements Serializable {
private int sid;
private String sname;
private String sex;
//在多方定义一个一方的引用
private Grade grade;

public Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}

public Student() {

}

public Student(int sid, String sname, String sex) {
this.sid = sid;
this.sname = sname;
this.sex = sex;
}
public Student(String sname, String sex) {
this.sname = sname;
this.sex = sex;
}

}


Student.hm.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">
<!-- Generated 2016-4-12 21:51:49 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.imooc.entity.Student" table="student">
<id name="sid" type="int">
<column name="sid" />
<generator class="increment" />
</id>
<property name="sname" type="java.lang.String">
<column name="sname" />
</property>
<property name="sex" type="java.lang.String">
<column name="sex" />
</property>
<!-- 配置多对一关联关系 -->
<many-to-one name="grade" class="com.imooc.entity.Grade" column="gid"></many-to-one>
</class>
</hibernate-mapping>


Grade类如下:

package com.imooc.entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

public class Grade implements Serializable {
private int gid;
private String gname;
private String gdesc;
// 在一方定义一个多方的集合
private Set<Student> students = new HashSet<Student>();

public Set<Student> getStudents() {
return students;
}

public void setStudents(Set<Student> students) {
this.students = students;
}

public int getGid() {
return gid;
}

public void setGid(int gid) {
this.gid = gid;
}

public String getGname() {
return gname;
}

public void setGname(String gname) {
this.gname = gname;
}

public String getGdesc() {
return gdesc;
}

public void setGdesc(String gdesc) {
this.gdesc = gdesc;
}

// 构造方法
public Grade() {
super();
}

public Grade(int gid, String gname, String gdesc) {
this.gid = gid;
this.gname = gname;
this.gdesc = gdesc;
}

public Grade(String gname, String gdesc) {
this.gname = gname;
this.gdesc = gdesc;
}

}


Grade.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">
<!-- Generated 2016-4-12 21:51:49 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.imooc.entity.Grade" table="grade">
<id name="gid" type="int">
<column name="gid" />
<generator class="increment" />
</id>
<property name="gname" type="java.lang.String">
<column name="gname"  length="20" not-null="true"/>
</property>
<property name="gdesc" type="java.lang.String">
<column name="gdesc" />
</property>
<!--  配置一对多关联关系-->
<set name="students" table="student">
<key column="gid"></key>
<one-to-many class="com.imooc.entity.Student"/>
</set>
</class>
</hibernate-mapping>


Test测试

保存学生和班级

//将学生添加到班级
public static void add()
{
Grade g = new Grade("一年级一班", "xx小学一年级一班");
Student s1 = new Student("张三", "男");
Student s2 = new Student("小美", "女");

//设置关系
g.getStudents().add(s1);
g.getStudents().add(s2);
s1.setGrade(g);
s2.setGrade(g);

Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
session.save(g);
session.save(s1);
session.save(s2);
transaction.commit();
HibernateUtil.closeSession(session);
}


此时控制台会有如下的输出:

Hibernate: select max(gid) from grade
Hibernate: select max(sid) from student
Hibernate: insert into grade (gname, gdesc, gid) values (?, ?, ?)
Hibernate: insert into student (sname, sex, gid, sid) values (?, ?, ?, ?)
Hibernate: insert into student (sname, sex, gid, sid) values (?, ?, ?, ?)
Hibernate: update student set gid=? where sid=?
Hibernate: update student set gid=? where sid=?


会发现有2条update语句,这两句话其实是多余的,如何去掉这两句话?

inverse
set节点的属性,指定关联关系的控制方向,默认值为false,表示不反转,也就是由一方来维护。在此处,也就是不需要班级来维护关联关系。

在关联关系中,inverse=”false”,则为主动方,表示由主动方负责维护关联关系。

在一对多关联中,只能是指one方的inverse为true,这将有助于性能的改善。

修改Grade.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">
<!-- Generated 2016-4-12 21:51:49 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.imooc.entity.Grade" table="grade">
<id name="gid" type="int">
<column name="gid" />
<generator class="increment" />
</id>
<property name="gname" type="java.lang.String">
<column name="gname"  length="20" not-null="true"/>
</property>
<property name="gdesc" type="java.lang.String">
<column name="gdesc" />
</property>
<!--  配置一对多关联关系-->
<set name="students" table="student" inverse="true">
<key column="gid"></key>
<one-to-many class="com.imooc.entity.Student"/>
</set>
</class>
</hibernate-mapping>


测试后,控制输出的语句为:

Hibernate: select max(gid) from grade
Hibernate: select max(sid) from student
Hibernate: insert into grade (gname, gdesc, gid) values (?, ?, ?)
Hibernate: insert into student (sname, sex, gid, sid) values (?, ?, ?, ?)
Hibernate: insert into student (sname, sex, gid, sid) values (?, ?, ?, ?)


此时就没有update语句了。

级联操作

cascade属性,当设置cascade属性不为none时,Hibernate会自动持久化所关联的对象。

cascade属性的设置会带来性能上的变动,需谨慎设置。

属性值含义和作用
all对所有操作进行级联操作
save-update执行保存和更新操作时进行级联操作
delete执行删除操作是进行级联操作
none对所有操作不进行级联操作
如下:

<set name="students" table="student" inverse="true" cascade="save-update">
<key column="gid"></key>
<one-to-many class="com.imooc.entity.Student"/>
</set>


由学生获取班级信息

//查询学生所在班级信息
public static void findGradeByStudent()
{
Session session = HibernateUtil.getSession();
Student stu = (Student) session.get(Student.class, 2);
System.out.println(stu.getSid()+","+stu.getSname()+","+stu.getSex());
Grade g = stu.getGrade();
System.out.println(g.getGid()+","+g.getGname()+","+g.getGdesc());
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hibernate