什么叫做单向一对多的映射呢?

我们首先要知道映射是有方向的,分为单向和双向。

比如班级和学生。站在班级的角度,一个班级可以有多个学生,  在这里班级就是“一”方 学生就是“多”方

这种关系就是一对多的关系,如果只站在班级的角度,那就是单向的一对多的关系。

一对多的关系我们应该怎么实现呢?

在数据库中我们会通过主外键的方式实现,在多学生表中添加一个外键指向班级

在hibernate中我们会通过在“一”的一方使用<set>元素表示持有“多”的一方的对象,即在“一”方中使用集合 表示持有“多”方

使用工具

hibernate配置文件


<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration>

<session-factory>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.url">
jdbc:mysql://localhost:3306/susu
</property>
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="myeclipse.connection.profile">MySQLDriver</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">create</property>
<mapping resource="com/scx/entity/Grade.hbm.xml" />
<mapping resource="com/scx/entity/Students.hbm.xml" />

</session-factory>

</hibernate-configuration>

因为我们还没有在数据库中创建表 所以要在

hibernate配置文件设置


<property name="hbm2ddl.auto">create</property>


持久化类

students   学生类


package com.scx.entity;

public class Students {
//学生主键
private int sId;
//学生姓名
private String sName;
//学生性别
private String sex;
//学生年龄
private int age;

public Students(int sId, String sName, String sex, int age) {
this.sId = sId;
this.sName = sName;
this.sex = sex;
this.age = age;
}

public Students() {
}

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 int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

}



grade  班级类


package com.scx.entity;

import java.util.HashSet;
import java.util.Set;

public class Grade {
//班级主键
private int gId;
//班级名称
private String gName;
//学生集合
private Set<Students> students = new HashSet<Students>();

public Grade(int gId, String gName, Set<Students> students) {
this.gId = gId;
this.gName = gName;
this.students = students;
}

public Grade() {
}

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 Set<Students> getStudents() {
return students;
}

public void setStudents(Set<Students> students) {
this.students = students;
}
//向班级中集合中添加学生
public void addStudents(Students stu) {
students.add(stu);
}
}

对象关系映射文件

Students.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.scx.entity.Students" table="students" catalog="hibernate">
<id name="sId" type="java.lang.Integer">
<column name="SID" />
<generator class="native" />
</id>
<property name="sName" type="java.lang.String">
<column name="SNAME" length="20" />
</property>
<property name="sex" type="java.lang.String">
<column name="SEX" length="2" />
</property>
<property name="age" type="java.lang.Integer">
<column name="AGE" />
</property>
</class>
</hibernate-mapping>

Grade.hbm.xml


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="com.scx.entity.Grade" table="grade" catalog="hibernate">
<id name="gId" type="java.lang.Integer">
<column name="GID" />
<generator class="native" />
</id>
<property name="gName" type="java.lang.String">
<column name="GNAME" length="20" />
</property>
<!-- 配置单向的一对多关联关系 -->
<set name="students" table="students">
<!-- 制定关联的外键列 -->
<key column="GID"></key>
<!-- 持久化对象所对应的实体类 -->
<one-to-many class="com.scx.entity.Students"/>
</set>
</class>
</hibernate-mapping>


注意看 在Grade.hbm.xml中我们需要配置单向的一对多关联关系


<set name="students" table="students">
<!-- 制定关联的外键列 -->
<key column="GID"></key>
<!-- 持久化对象所对应的实体类 -->
<one-to-many class="com.scx.entity.Students"/>
</set>

使用junit通过Hibernate API编写访问数据库的代码


import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;

import com.scx.entity.Grade;
import com.scx.entity.Students;


public class Test {
private Configuration config;
private ServiceRegistry serviceRegistry;
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init() {
//创建配置对象
config = new Configuration().configure();
//创建服务注册对象
serviceRegistry = new ServiceRegistryBuilder().applySettings(
config.getProperties()).buildServiceRegistry();
//创建会话工厂对象
sessionFactory=config.buildSessionFactory(serviceRegistry);
//会话对象
session=sessionFactory.openSession();
//开启事务
transaction=session.beginTransaction();
}
@After
public void destroy(){
transaction.commit();//提交事务
session.close();//关闭会话
sessionFactory.close();//关闭会话工厂
}
@org.junit.Test
public void testSave(){
Students stu1=new Students(1, "小明", "男", 15);
Students stu2=new Students(2, "小红", "女", 15);
Grade g1=new Grade();
Grade g2=new Grade();
g1.setgName("软件一班");
g2.setgName("软件二班");
g1.addStudents(stu1);
g2.addStudents(stu2);
session.save(g1);
session.save(g2);
session.save(stu1);
session.save(stu2);
}
}


实例化了两个学生 两个班级 分别属于一个班级 

运行结果如下:

hibernate初探之单向一对多映射_xml


根据班级查找班级所有学生

首先修改hibernate配置文件中的生成表策略为update


<property name="hbm2ddl.auto">update</property>


然后新添加一个测试


@org.junit.Test
public void findStudentsByGrade(){
Grade g=(Grade) session.get(Grade.class, 1);
System.out.println(g.getgName());
Set<Students> students=g.getStudents();
for (Students stu : students) {
System.out.println(stu.getsName()+" "+stu.getSex()+" "+stu.getAge());
}
}

运行结果:

hibernate初探之单向一对多映射_hibernate_02

更新学生信息


@org.junit.Test
public void update(){
Grade g=new Grade();
g.setgName("软件三班");
Students stu=(Students) session.get(Students.class, 1);
g.addStudents(stu);
session.save(g);
}

新建一个班级为软件三班 并将编号为1的学生添加到软件三班

运行结果:

hibernate初探之单向一对多映射_单向一对多映射_03

删除学生


@org.junit.Test
public void delete(){
Students stu=(Students) session.get(Students.class, 2);
session.delete(stu);
}

查找编号为2的学生 并删除

运行结果如下:

hibernate初探之单向一对多映射_hibernate_04