hibernate一对多关联OneToMany

知兮丶青
阅读(578) 2017-12-27
hibernate一对多关联OneToMany
hibernate一对多关联OneToMany

hibernate中一对多相对来说使用的比较多,如订单与商品,班级与学生,部门与员工等等,简单的说就是一个部门有多个员工。


一对多关联,使用@OneToMany、@ManyToOne


一对多单向

部门表:Department

一对多注解@OneToMany(单向)

如果只写@OneToMany的话,hibernbate会建一张表,维护他们之间的关系,

加上@JoinColumn(name="dept_id"),则不会建中间表,他会在多的一端加上外键dept_id,来维护他们之间的关系

package com.weizhixi.entity;

import java.util.Set;
import javax.persistence.*;

@Entity
public class Department {
   private int id;
   private String name;
   private Set<Employee> employee;

   @Id
   @GeneratedValue
   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;
   }
   @OneToMany(fetch=FetchType.LAZY,cascade = CascadeType.ALL)
   @JoinColumn(name="dept_id")
   public Set<Employee> getEmployee() {
      return employee;
   }
   public void setEmployee(Set<Employee> employee) {
      this.employee = employee;
   }
}

员工表:Employee

单向这里无需配置

package com.weizhixi.entity;

import javax.persistence.*;

@Entity
public class Employee {
   private int id;
   private String name;

   @Id
   @GeneratedValue
   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;
   }
}


添加数据

session = sessionFactory.getCurrentSession();
session.beginTransaction();

//创建部门
Department dept = new Department();
dept.setName("IT");
//创建员工集合
Set<Employee> employee = new HashSet<Employee>();
Employee emp1 = new Employee();
emp1.setName("Mr.Chen");
Employee emp2 = new Employee();
emp2.setName("Mr.Li");
employee.add(emp1);
employee.add(emp2);
//把员工分配到部门
dept.setEmployee(employee);
//保存
session.save(dept);

session.getTransaction().commit();

联级添加,发送的SQL

Hibernate: insert into Department (name) values (?)

Hibernate: insert into Employee (name) values (?)

Hibernate: insert into Employee (name) values (?)

Hibernate: update Employee set dept_id=? where id=?

Hibernate: update Employee set dept_id=? where id=?


查询数据

session = sessionFactory.getCurrentSession();
session.beginTransaction();

Query query = session.createQuery("FROM Department");
List<Department> depts = query.list();
//部门
for(Department dept: depts){
   System.out.println(dept.getName());
   //部门下员工
   for(Employee emp: dept.getEmployee()){
      System.out.println("\t"+emp.getName());
   }
}

session.getTransaction().commit();

懒加载输出:

Hibernate: select department0_.id as id5_, department0_.name as name5_ from Department department0_
IT
Hibernate: select employee0_.dept_id as dept3_1_, employee0_.id as id1_, employee0_.id as id4_0_, employee0_.name as name4_0_ from Employee employee0_ where employee0_.dept_id=?
	Mr.Li
	Mr.Chen

部门表:

mysql> select * from department;
+----+------+
| id | name |
+----+------+
|  1 | IT   |
+----+------+
1 row in set (0.00 sec)

员工表:

mysql> select * from employee;
+----+---------+---------+
| id | name    | dept_id |
+----+---------+---------+
|  1 | Mr.Li   |       1 |
|  2 | Mr.Chen |       1 |
+----+---------+---------+
2 rows in set (0.00 sec)



一对多双向

部门表:Department

一对多双向,在一的一端中设置mappedBy,说明多的一端为指导。

如果指定了外键字段名称,则多的一端也需要指定相同的字段名称。

package com.weizhixi.entity;

import java.util.Set;
import javax.persistence.*;

@Entity
public class Department {
   private int id;
   private String name;
   private Set<Employee> employee;

   @Id
   @GeneratedValue
   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;
   }
   @OneToMany(fetch=FetchType.LAZY,cascade = CascadeType.ALL)
   @JoinColumn(name="dept_id")
   public Set<Employee> getEmployee() {
      return employee;
   }
   public void setEmployee(Set<Employee> employee) {
      this.employee = employee;
   }
}

员工表:Employee

一对多双向,需要指定外键与一的一端给的外键名称一致,@JoinColumn(name="dept_id")

也可以不指定,如果在多的一端不指定,则一的一端也不能指定,否则为生成两个外键。

package com.weizhixi.entity;

import javax.persistence.*;

@Entity
public class Employee {
   private int id;
   private String name;
   private Department department;

   @Id
   @GeneratedValue
   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;
   }
   @ManyToOne
   @JoinColumn(name="dept_id")
   public Department getDepartment() {
      return department;
   }
   public void setDepartment(Department department) {
      this.department = department;
   }
}

查询数据

session = sessionFactory.getCurrentSession();
session.beginTransaction();

Query query = session.createQuery("FROM Employee");
List<Employee> emps = query.list();
for(Employee emp: emps){
   System.out.println("\t"+emp.getName() + "\t -\t"+emp.getDepartment().getName());
}

session.getTransaction().commit();

关联输出:

Hibernate: select employee0_.id as id4_, employee0_.dept_id as dept3_4_, employee0_.name as name4_ from Employee employee0_
Hibernate: select department0_.id as id5_0_, department0_.name as name5_0_ from Department department0_ where department0_.id=?
	Mr.Li	 -	IT
	Mr.Chen	 -	IT



原创文章,转载请注明出处:https://www.weizhixi.com/article/42.html