本例以Windows, JDK1.8, MySQL5 为基础,演示使用Hibernate5以注解的方式完成多对一的双向关系映射。

如果是双向关系关联,在多对一和一对多,存在相互的转换的过程,在一对多种,一方持有多方的集合,而多方持有一方的集合,而在多对一当中,多方持有一方的外键,一方持有多方的集合,也就是看站在那一方的角度,关于一对多的关系映射:Hibernate5 One-To-Many 一对多 Demo (Annotation)

使用的工具及技术

1.Hibernate 5.2.10.Final
2.MySQL 5
3.Eclipse
4.Maven 3

多对一的表的关系

Model

分别创建EmployeeCompany两个Model对象,在映射关系上,多个Employee对应一个Company

File : Employee.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package com.devnp.hibernate.association.mto.model;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "Employee")
public class Employee {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "E_ID")
private Long eId ;

@Column(name = "E_NAME")
private String eName ;

@Column(name = "E_AGE")
private Integer eAge ;

@ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.ALL)
@JoinColumn(name="CID", referencedColumnName="C_ID")
private Company company ;

public Employee() {
super();
}

public Employee(String eName, Integer eAge) {
super();
this.eName = eName;
this.eAge = eAge;
}

public Long geteId() {
return eId;
}

public void seteId(Long eId) {
this.eId = eId;
}

public String geteName() {
return eName;
}

public void seteName(String eName) {
this.eName = eName;
}

public Integer geteAge() {
return eAge;
}

public void seteAge(Integer eAge) {
this.eAge = eAge;
}

public Company getCompany() {
return company;
}

public void setCompany(Company company) {
this.company = company;
}

}

File : Company.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.devnp.hibernate.association.mto.model;

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

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "Company")
public class Company {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "C_ID")
private Long cId ;

@Column(name = "C_NAME")
private String cName ;

@OneToMany(fetch = FetchType.LAZY, cascade=CascadeType.ALL, mappedBy="company")
private Set<Employee> employees = new HashSet<Employee>() ;

public Company() {
super();
}

public Company(String cName) {
super();
this.cName = cName;
}

public Long getcId() {
return cId;
}

public void setcId(Long cId) {
this.cId = cId;
}

public String getcName() {
return cName;
}

public void setcName(String cName) {
this.cName = cName;
}

public Set<Employee> getEmployees() {
return employees;
}

public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}



}

Hibernate SessionFactory

本例以属性配置的加载,更多获取SessionFactory的方式:Hibernate5 SessionFactory 的获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package com.devnp.hibernate.util;

import java.util.Properties;

import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

import com.devnp.hibernate.association.mto.model.Company;
import com.devnp.hibernate.association.mto.model.Employee;
import com.devnp.hibernate.association.otm.model.Book;
import com.devnp.hibernate.association.otm.model.Person;
import com.devnp.hibernate.association.oto.model.Student;
import com.devnp.hibernate.association.oto.model.Transcripts;

public class HibernateProUtil {

private static SessionFactory sessionFactory = buildSessionFactory();

private static SessionFactory buildSessionFactory() {
Properties properties = new Properties();
properties.put("hibernate.dialect","org.hibernate.dialect.MySQL5InnoDBDialect"); //数据库方言
properties.put("hibernate.show_sql", "true"); //是否打印SQL
properties.put("hibernate.hbm2ddl.auto","update"); //执行跟新,及如果表不存在则会自动创建表

properties.put("hibernate.format_sql", "true"); //格式化

properties.put("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
properties.put("hibernate.connection.password", "!qaz2wsx");
properties.put("hibernate.connection.url", "jdbc:mysql://localhost:3306/test");
properties.put("hibernate.connection.username", "root");

/*StandardServiceRegistryBuilder standardServiceRegistryBuilder = new StandardServiceRegistryBuilder();
standardServiceRegistryBuilder.applySettings(properties);

MetadataSources metadataSources = new MetadataSources(standardServiceRegistryBuilder.build());
metadataSources.addAnnotatedClass(Student.class);*/

StandardServiceRegistry serviceRegistry= new StandardServiceRegistryBuilder().applySettings(properties).build();

MetadataSources metadataSources = new MetadataSources(serviceRegistry);
metadataSources.addAnnotatedClass(Student.class).addAnnotatedClass(Transcripts.class);

metadataSources.addAnnotatedClass(Person.class).addAnnotatedClass(Book.class);

metadataSources.addAnnotatedClass(Employee.class).addAnnotatedClass(Company.class);

Metadata metadata = metadataSources.getMetadataBuilder().applyImplicitNamingStrategy(
ImplicitNamingStrategyJpaCompliantImpl.INSTANCE).build();

sessionFactory = metadata.getSessionFactoryBuilder().build();

return sessionFactory;
}

public static SessionFactory getSessionFactory() {
return sessionFactory;
}

public static void shutdown() {
// Close caches and connection pools
getSessionFactory().close();
}
}

测试

以添加两个员工和一个公司为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 创建多个员工信息并保存
*/
public static void save(){
SessionFactory sessionFactory = HibernateProUtil.getSessionFactory();

Session session = sessionFactory.openSession();

session.getTransaction().begin();


Company company = new Company("devnp.com");

Employee employee1 = new Employee("JACK", 22);
Employee employee2 = new Employee("Alen", 25);

employee1.setCompany(company);
employee2.setCompany(company);

session.save(employee1);
session.save(employee2);

session.getTransaction().commit();

HibernateProUtil.shutdown();

}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
--Hibernate: 

create table Company (
C_ID bigint not null auto_increment,
C_NAME varchar(255),
primary key (C_ID)
) engine=InnoDB
--Hibernate:

create table Employee (
E_ID bigint not null auto_increment,
E_AGE integer,
E_NAME varchar(255),
CID bigint,
primary key (E_ID)
) engine=InnoDB
--Hibernate:

alter table Employee
add constraint FKq3wcxuroflbk632vkfs6c87ht
foreign key (CID)
references Company (C_ID)
--Hibernate:
insert
into
Company
(C_NAME)
values
(?)
--Hibernate:
insert
into
Employee
(CID, E_AGE, E_NAME)
values
(?, ?, ?)
--Hibernate:
insert
into
Employee
(CID, E_AGE, E_NAME)
values
(?, ?, ?)

更多测试

查询信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void select(){
SessionFactory sessionFactory = HibernateProUtil.getSessionFactory();

Session session = sessionFactory.openSession();

session.getTransaction().begin();

Employee employee = session.get(Employee.class, 1L);

System.out.println("Company ID : " + employee.getCompany().getcId() + " Name : " + employee.getCompany().getcName());

session.getTransaction().commit();

HibernateProUtil.shutdown();
}

查询信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void select(){
SessionFactory sessionFactory = HibernateProUtil.getSessionFactory();

Session session = sessionFactory.openSession();

session.getTransaction().begin();

Employee employee = session.get(Employee.class, 1L);

System.out.println("Company ID : " + employee.getCompany().getcId() + " Name : " + employee.getCompany().getcName());

session.getTransaction().commit();

HibernateProUtil.shutdown();
}

更新信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void update(){
SessionFactory sessionFactory = HibernateProUtil.getSessionFactory();

Session session = sessionFactory.openSession();

session.getTransaction().begin();

Employee employee = session.get(Employee.class, 1L);

employee.getCompany().setcName("www.devnp.com");

session.update(employee);

session.getTransaction().commit();

HibernateProUtil.shutdown();
}

删除信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void delete(){
SessionFactory sessionFactory = HibernateProUtil.getSessionFactory();

Session session = sessionFactory.openSession();

session.getTransaction().begin();

Employee employee = session.get(Employee.class, 1L);

session.delete(employee);

session.getTransaction().commit();

HibernateProUtil.shutdown();
}

代码下载

java-hibernate-association-demo.zip