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. something good

    CF292A CF304B CF383A CF409D CF409F CF632A CF652B CF656A CF656B CF656D CF659A CF678A CF697A CF735D CF ...

  2. [opengl] 画一个可移动的自行车 二维几何变换(平移、旋转、缩放)

    #include <cmath> #include "glut.h" #include "iostream" using namespace std ...

  3. Android系列教程之前言

    内容转载自我自己的博客 目前安卓的主流开发语言是Java,在正式开始Android系列的教程之前,需要知道一些基本内容 Android介绍 Android['ændrɔid] 是一个基于Linux 内 ...

  4. spring applicationContext.xml文件移到resources目录下

    SpringMVC的框架默认目录结构 修改后的目录结构及web.xml 同时在pom里的配置:将resources目录打包到web-inf/classes目录下<resources>   ...

  5. sql server还原数据库(请选择用于还原的备份集)

    还原数据库的时候明明选择了备份集,还是提示未选择还原的备份集 后来查了下,是因为我本地有两个数据库(2008R2和2014),对应的两个数据库实例.而还原bak是sqlserver2014的备份,我默 ...

  6. AIX7.1安装zabbix_agent3.4

    1.在zabbix官网https://www.zabbix.com/download下载Zabbix pre-compiled agents 2.Zabbix pre-compiled agents安 ...

  7. Python识别璇玑图中诗的数量

    一.璇玑图简介 璇玑图的读法有很多,这里我使用七七棋盘格的读法,在璇玑图中分离出一个七七棋盘格,如下表 吏 官 同 流 污 合 玩 痞 悍 蒙 骗 造 假 蛋 鸡 宴 请 客 友 朋 远 戚 偏 正 ...

  8. HttpsUtils

    package io.renren.modules.jqr.util; import java.io.BufferedReader; import java.io.InputStream; impor ...

  9. .net core 实现基于 cron 表达式的任务调度

    .net core 实现基于 cron 表达式的任务调度 Intro 上次我们实现了一个简单的基于 Timer 的定时任务,详细信息可以看这篇文章. 但是使用过程中慢慢发现这种方式可能并不太合适,有些 ...

  10. .net core 基于 IHostedService 实现定时任务

    .net core 基于 IHostedService 实现定时任务 Intro 从 .net core 2.0 开始,开始引入 IHostedService,可以通过 IHostedService ...