开发过程中难免会碰到一对多、多对一的关系,比如一个学生属于一个班级,而一个班级里面有多个学生,一个部门有多个员工等,这种情况就需要用数据库表与表之间的关联关系,如果不用关联关系,维护数据库表格将会变得非常麻烦。下面以多个学生属于一个班级介绍在hibernate中数据库表中1-n的关联关系配置方法。
一、hibernate一对多双向关联映射的方法如下
(1) 一的一端,在set元素中使用key元素来表明需要在对方的表中添加一个外键来指向一的一端
(2) 多的一端,则使用many-to-one元素来映射
二、具体配置实现
(1)建立一的一端的类Classes其代码如下:
package cn.test.Bean;
import java.util.HashSet;
import java.util.Set;
public class Classes {
private Long id;
private String name;
private Set<student> stus = new HashSet<student>();//来保存多个学生对应同一个班级
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<student> getStus() {
return stus;
}
public void setStus(Set<student> stus) {
this.stus = stus;
}
}
Classes.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>
<class name="cn.test.Bean.Classes" table="classes">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<set name="stus" table="student" inverse="true" cascade="save-update">
<key column="classId" not-null="true"></key>
<one-to-many class="cn.test.Bean.student"/>
</set>
</class>
</hibernate-mapping>
说明:在上述配置文件set元素中,inverse属性设置为true,表面主外键关键又student来维护,子元素key中,column属性指定student表中引用classes表的外键为classId,与student.hbm.xml文件中的many-to-one元素的column相对应。
(2)建立多的一端student类
package cn.test.Bean;
public class student {
private long id;
private String name;
private Classes classes;//与一的一端联系起来
public long getId() {
return id;
}
public void setId(long 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;
}
}
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>
<class name="cn.test.Bean.student" table="student">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"></property>
<many-to-one name="classes" class="cn.test.Bean.Classes" cascade="save-update" fetch="select" column="classId" not-null="true">
</many-to-one>
</class>
</hibernate-mapping>
说明:many-to-one中,name属性指定在student类中关联的类的属性为classes,cascade属性指定联级操作为save-update,也就是对类student对象保存或者更新会联级保存到Classes类对象。
(3)编写测试代码,让两个学生的信息同属于同一个班级
package cn.test.hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.Test;
import cn.test.Bean.Classes;
import cn.test.Bean.student;
public class TestStudent {
private SessionFactory sessionFactory;
@Test
public void testsave(){
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure() // configures settings from hibernate.cfg.xml
.build();
sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory();
Session session =sessionFactory.openSession();
Classes cl=new Classes();
student st1=new student();
student st2=new student();
st1.setName("小明");
st2.setName("小红");
cl.setName("一班");
st1.setClasses(cl);
st2.setClasses(cl);
session.beginTransaction();
session.save(st1);
session.save(st2);
session.getTransaction().commit();
session.close();
}
}
运行以后,可以看到在数据库student表中,两个学生的classId的值一样,保存的值为classes表中的id的值。