One to many映射关系指的是两个实体间一个实体可以和多个实体有关联关系,但是多的这一端只能和一的这一端的一个实例有关系。它是一个1 到 n的关系。例如在任何的公司员工可以注册多个银行账户,一个银行账户只能和一个员工相关联,在这篇文章中我们将会学习怎么在Hibernate3中建立这种映射关系。

问题陈述

我们要写两个实体一个是Employee实体另一个是Account实体,这样多个银行账户就可以和一个员工关联了,但是这些账户不能被两个或以上的用户共享。

设计解决方案

这种问题可以使用两种方式解决。一种方式是在Account表中设置一个外键EMPLOYEE_ID,这一列指向Employee表的主键,这种方式没有两个账号可以和多个用户相关联,显然,为了完成这种限制,账号应该是独特的。另一种方式是建立一个连接表,比如说是叫EMPLOYEE_ACCOUNT,这个表有两列,EMP_ID作为EMPLOYEE表中主键的外键,对于ACCOUNT_ID也是这种情况。

使用外键连接

这种方式,两个实体都要负责建立关系并维护这种关系,EMPLOYEE实体应该申明的关系是one to many,Account实体应该声明的关系是many  to one。首先来看一下关系设计:
EMPLOYEE实体
  1. package hibernate.test.oneToMany.foreignKeyAsso;
  2. import java.io.Serializable;
  3. import java.util.Set;
  4. import javax.persistence.CascadeType;
  5. import javax.persistence.Column;
  6. import javax.persistence.Entity;
  7. import javax.persistence.GeneratedValue;
  8. import javax.persistence.GenerationType;
  9. import javax.persistence.Id;
  10. import javax.persistence.JoinColumn;
  11. import javax.persistence.OneToMany;
  12. import javax.persistence.Table;
  13. import javax.persistence.UniqueConstraint;
  14. @Entity(name = "ForeignKeyAssoEntity")
  15. @Table(name = "Employee", uniqueConstraints = {
  16. @UniqueConstraint(columnNames = "ID"),
  17. @UniqueConstraint(columnNames = "EMAIL") })
  18. public class EmployeeEntity implements Serializable {
  19. private static final long serialVersionUID = -1798070786993154676L;
  20. @Id
  21. @GeneratedValue(strategy = GenerationType.IDENTITY)
  22. @Column(name = "ID", unique = true, nullable = false)
  23. private Integer employeeId;
  24. @Column(name = "EMAIL", unique = true, nullable = false, length = 100)
  25. private String email;
  26. @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)
  27. private String firstName;
  28. @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)
  29. private String lastName;
  30. @OneToMany(cascade=CascadeType.ALL)
  31. @JoinColumn(name="EMPLOYEE_ID")
  32. private Set<AccountEntity> accounts;
  33. public Integer getEmployeeId() {
  34. return employeeId;
  35. }
  36. public void setEmployeeId(Integer employeeId) {
  37. this.employeeId = employeeId;
  38. }
  39. public String getEmail() {
  40. return email;
  41. }
  42. public void setEmail(String email) {
  43. this.email = email;
  44. }
  45. public String getFirstName() {
  46. return firstName;
  47. }
  48. public void setFirstName(String firstName) {
  49. this.firstName = firstName;
  50. }
  51. public String getLastName() {
  52. return lastName;
  53. }
  54. public void setLastName(String lastName) {
  55. this.lastName = lastName;
  56. }
  57. public Set<AccountEntity> getAccounts() {
  58. return accounts;
  59. }
  60. public void setAccounts(Set<AccountEntity> accounts) {
  61. this.accounts = accounts;
  62. }
  63. }

Account实体

  1. package hibernate.test.oneToMany.foreignKeyAsso;
  2. import java.io.Serializable;
  3. import javax.persistence.Column;
  4. import javax.persistence.Entity;
  5. import javax.persistence.GeneratedValue;
  6. import javax.persistence.GenerationType;
  7. import javax.persistence.Id;
  8. import javax.persistence.ManyToOne;
  9. import javax.persistence.Table;
  10. import javax.persistence.UniqueConstraint;
  11. @Entity(name = "ForeignKeyAssoAccountEntity")
  12. @Table(name = "ACCOUNT", uniqueConstraints = {
  13. @UniqueConstraint(columnNames = "ID")})
  14. public class AccountEntity implements Serializable
  15. {
  16. private static final long serialVersionUID = -6790693372846798580L;
  17. @Id
  18. @GeneratedValue(strategy = GenerationType.IDENTITY)
  19. @Column(name = "ID", unique = true, nullable = false)
  20. private Integer accountId;
  21. @Column(name = "ACC_NUMBER", unique = true, nullable = false, length = 100)
  22. private String accountNumber;
  23. @ManyToOne
  24. private EmployeeEntity employee;
  25. public Integer getAccountId() {
  26. return accountId;
  27. }
  28. public void setAccountId(Integer accountId) {
  29. this.accountId = accountId;
  30. }
  31. public String getAccountNumber() {
  32. return accountNumber;
  33. }
  34. public void setAccountNumber(String accountNumber) {
  35. this.accountNumber = accountNumber;
  36. }
  37. public EmployeeEntity getEmployee() {
  38. return employee;
  39. }
  40. public void setEmployee(EmployeeEntity employee) {
  41. this.employee = employee;
  42. }
  43. }

测试代码

  1. package hibernate.test.oneToMany;
  2. import hibernate.test.HibernateUtil;
  3. import hibernate.test.oneToMany.foreignKeyAsso.AccountEntity;
  4. import hibernate.test.oneToMany.foreignKeyAsso.EmployeeEntity;
  5. import java.util.HashSet;
  6. import java.util.Set;
  7. import org.hibernate.Session;
  8. public class TestForeignKeyAssociation
  9. {
  10. public static void main(String[] args)
  11. {
  12. Session session = HibernateUtil.getSessionFactory().openSession();
  13. session.beginTransaction();
  14. AccountEntity account1 = new AccountEntity();
  15. account1.setAccountNumber("Account detail 1");
  16. AccountEntity account2 = new AccountEntity();
  17. account2.setAccountNumber("Account detail 2");
  18. AccountEntity account3 = new AccountEntity();
  19. account3.setAccountNumber("Account detail 3");
  20. //Add new Employee object
  21. EmployeeEntity firstEmployee = new EmployeeEntity();
  22. firstEmployee.setEmail("demo-user-first@mail.com");
  23. firstEmployee.setFirstName("demo-one");
  24. firstEmployee.setLastName("user-one");
  25. EmployeeEntity secondEmployee = new EmployeeEntity();
  26. secondEmployee.setEmail("demo-user-second@mail.com");
  27. secondEmployee.setFirstName("demo-two");
  28. secondEmployee.setLastName("user-two");
  29. Set<AccountEntity> accountsOfFirstEmployee = new HashSet<AccountEntity>();
  30. accountsOfFirstEmployee.add(account1);
  31. accountsOfFirstEmployee.add(account2);
  32. Set<AccountEntity> accountsOfSecondEmployee = new HashSet<AccountEntity>();
  33. accountsOfSecondEmployee.add(account3);
  34. firstEmployee.setAccounts(accountsOfFirstEmployee);
  35. secondEmployee.setAccounts(accountsOfSecondEmployee);
  36. //Save Employee
  37. session.save(firstEmployee);
  38. session.save(secondEmployee);
  39. session.getTransaction().commit();
  40. HibernateUtil.shutdown();
  41. }
  42. }
  43. Output:
  44. Hibernate: insert into Employee (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
  45. Hibernate: insert into ACCOUNT (ACC_NUMBER, employee_ID) values (?, ?)
  46. Hibernate: insert into ACCOUNT (ACC_NUMBER, employee_ID) values (?, ?)
  47. Hibernate: insert into Employee (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
  48. Hibernate: insert into ACCOUNT (ACC_NUMBER, employee_ID) values (?, ?)
  49. Hibernate: update ACCOUNT set EMPLOYEE_ID=? where ID=?
  50. Hibernate: update ACCOUNT set EMPLOYEE_ID=? where ID=?
  51. Hibernate: update ACCOUNT set EMPLOYEE_ID=? where ID=?

使用关联表

这种方式使用关联表存储两个实体间的关系@JoinTable注解是用来建立这种关系的,先来看一下数据库模式
EMPLOYEE实体
  1. package hibernate.test.oneToMany.joinTable;
  2. import java.io.Serializable;
  3. import java.util.Set;
  4. import javax.persistence.CascadeType;
  5. import javax.persistence.Column;
  6. import javax.persistence.Entity;
  7. import javax.persistence.GeneratedValue;
  8. import javax.persistence.GenerationType;
  9. import javax.persistence.Id;
  10. import javax.persistence.JoinColumn;
  11. import javax.persistence.JoinTable;
  12. import javax.persistence.OneToMany;
  13. import javax.persistence.Table;
  14. import javax.persistence.UniqueConstraint;
  15. @Entity(name = "JoinTableEmployeeEntity")
  16. @Table(name = "Employee", uniqueConstraints = {
  17. @UniqueConstraint(columnNames = "ID"),
  18. @UniqueConstraint(columnNames = "EMAIL") })
  19. public class EmployeeEntity implements Serializable
  20. {
  21. private static final long serialVersionUID = -1798070786993154676L;
  22. @Id
  23. @GeneratedValue(strategy = GenerationType.IDENTITY)
  24. @Column(name = "ID", unique = true, nullable = false)
  25. private Integer employeeId;
  26. @Column(name = "EMAIL", unique = true, nullable = false, length = 100)
  27. private String email;
  28. @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)
  29. private String firstName;
  30. @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)
  31. private String lastName;
  32. @OneToMany(cascade=CascadeType.ALL)
  33. @JoinTable(name="EMPLOYEE_ACCOUNT", joinColumns={@JoinColumn(name="EMPLOYEE_ID", referencedColumnName="ID")}
  34. , inverseJoinColumns={@JoinColumn(name="ACCOUNT_ID", referencedColumnName="ID")})
  35. private Set<AccountEntity> accounts;
  36. public Integer getEmployeeId() {
  37. return employeeId;
  38. }
  39. public void setEmployeeId(Integer employeeId) {
  40. this.employeeId = employeeId;
  41. }
  42. public String getEmail() {
  43. return email;
  44. }
  45. public void setEmail(String email) {
  46. this.email = email;
  47. }
  48. public String getFirstName() {
  49. return firstName;
  50. }
  51. public void setFirstName(String firstName) {
  52. this.firstName = firstName;
  53. }
  54. public String getLastName() {
  55. return lastName;
  56. }
  57. public void setLastName(String lastName) {
  58. this.lastName = lastName;
  59. }
  60. public Set<AccountEntity> getAccounts() {
  61. return accounts;
  62. }
  63. public void setAccounts(Set<AccountEntity> accounts) {
  64. this.accounts = accounts;
  65. }
  66. }

Account实体

  1. package hibernate.test.oneToMany.joinTable;
  2. import java.io.Serializable;
  3. import javax.persistence.Column;
  4. import javax.persistence.Entity;
  5. import javax.persistence.GeneratedValue;
  6. import javax.persistence.GenerationType;
  7. import javax.persistence.Id;
  8. import javax.persistence.Table;
  9. import javax.persistence.UniqueConstraint;
  10. @Entity(name = "JoinTableAccountEntity")
  11. @Table(name = "ACCOUNT", uniqueConstraints = {
  12. @UniqueConstraint(columnNames = "ID")})
  13. public class AccountEntity implements Serializable
  14. {
  15. private static final long serialVersionUID = -6790693372846798580L;
  16. @Id
  17. @GeneratedValue(strategy = GenerationType.IDENTITY)
  18. @Column(name = "ID", unique = true, nullable = false)
  19. private Integer accountId;
  20. @Column(name = "ACC_NUMBER", unique = true, nullable = false, length = 100)
  21. private String accountNumber;
  22. public Integer getAccountId() {
  23. return accountId;
  24. }
  25. public void setAccountId(Integer accountId) {
  26. this.accountId = accountId;
  27. }
  28. public String getAccountNumber() {
  29. return accountNumber;
  30. }
  31. public void setAccountNumber(String accountNumber) {
  32. this.accountNumber = accountNumber;
  33. }
  34. }

在配置文件中配置实体,我们已经有了两个在运行时的实体,我们必须在配置文件中增加他们。请注意只有一个集合实体可以在配置文件中配置,否则会有意外的情况发生

  1. < ?xml version="1.0" encoding="utf-8"?>
  2. < !DOCTYPE hibernate-configuration PUBLIC
  3. "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
  5. <hibernate-configuration>
  6. <session-factory>
  7. <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  8. <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernatetest</property>
  9. <property name="hibernate.connection.password">XXXXXX</property>
  10. <property name="hibernate.connection.username">root</property>
  11. <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  12. <property name="show_sql">true</property>
  13. <property name="hbm2ddl.auto">create</property>
  14. <mapping clas="hibernate.test.oneToMany.foreignKeyAsso.AccountEntity"></mapping>
  15. <mapping clas="hibernate.test.oneToMany.foreignKeyAsso.EmployeeEntity"></mapping>
  16. </session-factory>
  17. </hibernate-configuration>

测试代码:

    1. package hibernate.test.oneToMany;
    2. import hibernate.test.HibernateUtil;
    3. import hibernate.test.oneToMany.joinTable.AccountEntity;
    4. import hibernate.test.oneToMany.joinTable.EmployeeEntity;
    5. import java.util.HashSet;
    6. import java.util.Set;
    7. import org.hibernate.Session;
    8. public class TestJoinTable
    9. {
    10. public static void main(String[] args)
    11. {
    12. Session session = HibernateUtil.getSessionFactory().openSession();
    13. session.beginTransaction();
    14. AccountEntity account1 = new AccountEntity();
    15. account1.setAccountNumber("123-345-65454");
    16. AccountEntity account2 = new AccountEntity();
    17. account2.setAccountNumber("123-345-6542222");
    18. //Add new Employee object
    19. EmployeeEntity emp = new EmployeeEntity();
    20. emp.setEmail("demo-user@mail.com");
    21. emp.setFirstName("demo");
    22. emp.setLastName("user");
    23. Set<AccountEntity> accounts = new HashSet<AccountEntity>();
    24. accounts.add(account1);
    25. accounts.add(account2);
    26. emp.setAccounts(accounts);
    27. //Save Employee
    28. session.save(emp);
    29. session.getTransaction().commit();
    30. HibernateUtil.shutdown();
    31. }
    32. }
    33. Output:
    34. Hibernate: insert into Employee (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)
    35. Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)
    36. Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)
    37. Hibernate: insert into EMPLOYEE_ACCOUNT (EMPLOYEE_ID, ACCOUNT_ID) values (?, ?)
    38. Hibernate: insert into EMPLOYEE_ACCOUNT (EMPLOYEE_ID, ACCOUNT_ID) values (?, ?)

使用注解的Hibernate one-to-many映射的更多相关文章

  1. hibernate的对象/关系映射结果为空,exists查不到值的问题-20190823

    1: hibernate的对象/关系映射 情景:在使用@onetotone/@manytonone时关联结果为空 原因:在使用这个注解的时候,默认的时crossjoin(交叉连接),在进行查询时以及排 ...

  2. Hibernate多对多关系映射(建表)

    下边讲述Hibernate多对多关系映射. 多对多关系的表的结构为: 两个实体表,还包含一个关系表,关系表为复合主键,如果要使用Hibernate多对多关系映射,则关系表必须只包含两个字段,如果生成了 ...

  3. Hibernate入门3.配置映射文件深入

    Hibernate入门3.配置映射文件深入 2013.11.27 前言: 之前的两节是在Java项目中如何使用hibernate,并且通过一个简单地项目实践,期间有很多的错误,一般都是因为配置包的问题 ...

  4. 菜鸟学习Hibernate——多对多关系映射

    Hibernate中的关系映射,最常见的关系映射之一就是多对多关系映射例如用户与角色的关系,一个用户对应多个角色,一个角色对应多个用户.如图: Hibernate中如何来映射这两个的关系呢? 下面就为 ...

  5. 菜鸟学习Hibernate——一对多关系映射

    Hibernate中的关系映射,最常见的关系映射之一就是一对多关系映射例如学生与班级的关系,一个班级对应多个学生.如图: Hibernate中如何来映射这两个的关系呢? 下面就为大家讲解一下: 1.创 ...

  6. Hibernate一对一双向关联映射

    关键原因在于对象模型具有方向性: 单向:一端只能加载另一端,不能反过来. 双向:两端都可以加载另一端. 问题来了:如何我们想从身份证端(IdCard)加载人(Person),怎么办呢? 下面我们开始介 ...

  7. Hibernate之1-N关联映射

    一.Hibernate之1-N关联映射 1. 哪边是 1 , 哪边是多 ?      须要从业务的角度来说明.比如,Employee 和 Department 之间就是 n-1 的关联关系,Order ...

  8. Hibernate一对一主键映射

    Hibernate一对一主键映射                        ------------------------------                            -- ...

  9. Hibernate一对一外键映射

    Hibernate 一对一外键映射                    ------------------------------                            ----- ...

  10. Eclipse从数据库逆向生成Hibernate实体类和映射文件(Eclipse插件系列之HibernateTools)

    ♣下载安装Eclipse插件(HibernateTools) ♣Eclipse连接数据库(Mysql5.7) ♣新建hibernate.properties和hibernate.cfg.xml文件 ♣ ...

随机推荐

  1. Java中的Enumeration、Iterable和Iterator接口详解

    前言 在看各类Java书籍或者博文的时候,总是会遇到Enumeration.Iterable和Iterator这三个接口,如果对这几个接口不是很明白的话,总会让自己看着看着就迷惑了,正好这周末,抽空把 ...

  2. 个人永久性免费-Excel催化剂功能第105波-批量调整不规范的图形对象到单一单元格内存储

    在日常制表过程中,一个不得不面对的问题,许多的工作起点是基于其他人加工过的表格,无论自己多大的本领,面对不规范的其他人的制作的表格,经过自己的手,该擦的屁股还是要自己去亲手去擦,而带出来的也只会是一堆 ...

  3. 个人永久性免费-Excel催化剂功能第88波-批量提取pdf文件信息(图片、表格、文本等)

    日常办公场合中,除了常规的Excel.Word.PPT等文档外,还有一个不可忽略的文件格式是pdf格式,而对于想从pdf文件中获取信息时,常规方法将变得非常痛苦和麻烦.此篇给大家送一pdf文件提取信息 ...

  4. 2019年7月20日 - LeetCode0002

    https://leetcode-cn.com/problems/add-two-numbers/submissions/ 我的方法: /** * Definition for singly-link ...

  5. MySql的数据库优化到底优化啥了都(3)

    嘟嘟在上两个文章里面简单粗糙的讲了讲关于MySql存储引擎的一些特性以及选择.个人感觉如果面试官给我机会的话,至少能说个10分钟了吧.只可惜有时候生活就是这样:骨感的皮包骨头了还在那美呢.牢骚两句,北 ...

  6. python的乘法口诀表

    python的乘法口诀表 python的乘法口诀表 用python来写一个脚本,使得这个脚本在运行后自动输出乘法口诀表. pyton的脚本如下: #!/usr/bin/env python #codi ...

  7. python带有GIL解释器锁

    1.GIL是什么?GIL的全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定. 2.每个CPU在同一时间只能执行一个线程(在 ...

  8. js,ts操作dom总结

    以上面为例: js获取placeholder节点 : document.getElementsByClassName("newTicket")[0].getAttributeNod ...

  9. HTTP文件上传原理

    前言 对于这块知识点,我一直都是模糊的,不是非常清楚的.在平时的工作中,遇到上传的问题,也没有深入的去研究过,也都是直接用别人封装好的类来完成自己的工作.某一天,看了本书,说到这个知识点,一脸茫然,觉 ...

  10. 模拟器无Back、Menu等键

    问题如图所示: 解决方法: 1. 打开Android Virtual Device (AVD) Manager --> 选择模拟器,并点击edit --> 勾选KeyBoard中的选项,并 ...