在实际开发中,一对多的例子有很多,比如一个部门对应多个员工,这就是一种典型一对多的关系,在Hibernate中使用一对多映射可以使用一方来管理多方,这显然是很方便的。在本例中,使用了2个实体,一是员工employee,另外一个是部门department。
首先创建2张表:
接下来就是创建一个project了,整个工程的骨架如下图所示:
先看pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Demo</groupId>
<artifactId>HibernateDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>HibernateDemo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.2</version>
<scope>test</scope>
</dependency>
<!-- 添加Hibernate依赖 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.0.Final</version>
</dependency>
<!-- 添加Log4J依赖 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.6.4</version>
</dependency>
<!-- mysql数据库的驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
</project>
再看两个实体类Employee和Department:
package entity;
public class Employee {
private int empId;
private String empName;
public Employee() {
super();
}
public Employee(String empName) {
super();
this.empName = empName;
}
public Employee(int empId, String empName) {
super();
this.empId = empId;
this.empName = empName;
}
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
@Override
public String toString() {
return "Employee [empId=" + empId + ", empName=" + empName + "]";
}
}
package entity;
import java.util.Set;
public class Department {
private int deptId;
private String deptName;
private Set<Employee> employees;
public Department() {
super();
}
public Department(String deptName) {
super();
this.deptName = deptName;
}
public Department(int deptId, String deptName) {
super();
this.deptId = deptId;
this.deptName = deptName;
}
public int getDeptId() {
return deptId;
}
public void setDeptId(int deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public Set<Employee> getEmployees() {
return employees;
}
public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}
@Override
public String toString() {
return "Department [deptId=" + deptId + ", deptName=" + deptName + ", employees=" + employees + "]";
}
}
注意,因为是单向的一对多关联映射,所以在一方,也就是department方,建立一个Set类型的变量来保存多方的信息。同样,
在hbm.xml文件里面也会体现出这一点。
Employee.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 2017-10-8 19:42:28 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="entity.Employee" table="EMPLOYEE">
<id name="empId" type="java.lang.Integer">
<column name="EMP_ID" />
<generator class="native" />
</id>
<property name="empName" type="java.lang.String">
<column name="EMP_NAME" />
</property>
</class>
</hibernate-mapping>
Department.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 2017-10-8 19:42:28 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="entity.Department" table="DEPARTMENT">
<id name="deptId" type="java.lang.Integer">
<column name="DEPT_ID" />
<generator class="native" />
</id>
<property name="deptName" type="java.lang.String">
<column name="DEPT_NAME" />
</property>
<set name="employees" cascade="all" table="EMPLOYEE">
<key column="DEPT_ID"></key>
<one-to-many class="entity.Employee"/>
</set>
</class>
</hibernate-mapping>
然后就是hibernate的主配置文件了:
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_demo</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping resource="Department.hbm.xml"/>
<mapping resource="Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
接下来是工具类HibernateDAOHelper:
package util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
public class HibernateDAOHelper {
private static SessionFactory sessionFactory;
private static Session session;
static {
//从class目录自动获取hibernate主配置文件
Configuration config = new Configuration().configure();
//获取服务注册对象
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(config.getProperties()).build();
//获取会话工厂
sessionFactory = config.buildSessionFactory(serviceRegistry);
}
//获取会话对象
public static Session getSession() {
session = sessionFactory.openSession();
return session;
}
//关闭会话
public static void closeSession() {
if(session!=null) {
session.close();
}
}
}
最后是测试类,分别给出了CRUD的测试:
package test;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import entity.Department;
import entity.Employee;
import util.HibernateDAOHelper;
public class TestDemo{
@Test
public void addTest() {
Department dept = new Department("部门1");
Employee emp1 = new Employee("员工1");
Employee emp2 = new Employee("员工2");
Set<Employee> empSet = new HashSet<Employee>();
empSet.add(emp1);
empSet.add(emp2);
dept.setEmployees(empSet);
Session session = HibernateDAOHelper.getSession();
Transaction tx = session.beginTransaction();
session.save(dept);
tx.commit();
HibernateDAOHelper.closeSession();
}
@Test
public void queryTest() {
Session session = HibernateDAOHelper.getSession();
Department dept = (Department) session.get(Department.class, 1);
System.out.println(dept);
}
@Test
public void updateTest() {
Session session = HibernateDAOHelper.getSession();
Transaction tx = session.beginTransaction();
Department dept = (Department) session.get(Department.class, 1);
Employee emp = (Employee) session.get(Employee.class, 2);
dept.getEmployees().remove(emp);
session.update(dept);
tx.commit();
HibernateDAOHelper.closeSession();
}
@Test
public void deleteTest() {
Session session = HibernateDAOHelper.getSession();
Transaction tx = session.beginTransaction();
Department dept = (Department) session.get(Department.class, 1);
session.delete(dept);
tx.commit();
HibernateDAOHelper.closeSession();
}
}
在执行测试前,数据库里是没有数据的:
现在执行添加方法:
再执行查询方法:
执行更新方法:
执行删除方法: