使用注解的Hibernate one-to-many映射

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.   
  3. import java.io.Serializable;  
  4. import java.util.Set;  
  5.   
  6. import javax.persistence.CascadeType;  
  7. import javax.persistence.Column;  
  8. import javax.persistence.Entity;  
  9. import javax.persistence.GeneratedValue;  
  10. import javax.persistence.GenerationType;  
  11. import javax.persistence.Id;  
  12. import javax.persistence.JoinColumn;  
  13. import javax.persistence.OneToMany;  
  14. import javax.persistence.Table;  
  15. import javax.persistence.UniqueConstraint;  
  16.   
  17. @Entity(name = "ForeignKeyAssoEntity")  
  18. @Table(name = "Employee", uniqueConstraints = {  
  19. @UniqueConstraint(columnNames = "ID"),  
  20. @UniqueConstraint(columnNames = "EMAIL") })  
  21. public class EmployeeEntity implements Serializable {  
  22.   
  23.     private static final long serialVersionUID = -1798070786993154676L;  
  24.   
  25.     @Id  
  26.     @GeneratedValue(strategy = GenerationType.IDENTITY)  
  27.     @Column(name = "ID", unique = true, nullable = false)  
  28.     private Integer employeeId;  
  29.   
  30.     @Column(name = "EMAIL", unique = true, nullable = false, length = 100)  
  31.     private String email;  
  32.   
  33.     @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)  
  34.     private String firstName;  
  35.   
  36.     @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)  
  37.     private String lastName;  
  38.   
  39.     @OneToMany(cascade=CascadeType.ALL)  
  40.     @JoinColumn(name="EMPLOYEE_ID")  
  41.     private Set<AccountEntity> accounts;  
  42.   
  43.     public Integer getEmployeeId() {  
  44.         return employeeId;  
  45.     }  
  46.   
  47.     public void setEmployeeId(Integer employeeId) {  
  48.         this.employeeId = employeeId;  
  49.     }  
  50.   
  51.     public String getEmail() {  
  52.         return email;  
  53.     }  
  54.   
  55.     public void setEmail(String email) {  
  56.         this.email = email;  
  57.     }  
  58.   
  59.     public String getFirstName() {  
  60.         return firstName;  
  61.     }  
  62.   
  63.     public void setFirstName(String firstName) {  
  64.         this.firstName = firstName;  
  65.     }  
  66.   
  67.     public String getLastName() {  
  68.         return lastName;  
  69.     }  
  70.   
  71.     public void setLastName(String lastName) {  
  72.         this.lastName = lastName;  
  73.     }  
  74.   
  75.     public Set<AccountEntity> getAccounts() {  
  76.         return accounts;  
  77.     }  
  78.   
  79.     public void setAccounts(Set<AccountEntity> accounts) {  
  80.         this.accounts = accounts;  
  81.     }  
  82. }  

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

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

使用关联表

这种方式使用关联表存储两个实体间的关系@JoinTable注解是用来建立这种关系的,先来看一下数据库模式

EMPLOYEE实体
  1. package hibernate.test.oneToMany.joinTable;  
  2.   
  3. import java.io.Serializable;  
  4. import java.util.Set;  
  5.   
  6. import javax.persistence.CascadeType;  
  7. import javax.persistence.Column;  
  8. import javax.persistence.Entity;  
  9. import javax.persistence.GeneratedValue;  
  10. import javax.persistence.GenerationType;  
  11. import javax.persistence.Id;  
  12. import javax.persistence.JoinColumn;  
  13. import javax.persistence.JoinTable;  
  14. import javax.persistence.OneToMany;  
  15. import javax.persistence.Table;  
  16. import javax.persistence.UniqueConstraint;  
  17.   
  18. @Entity(name = "JoinTableEmployeeEntity")  
  19. @Table(name = "Employee", uniqueConstraints = {  
  20. @UniqueConstraint(columnNames = "ID"),  
  21. @UniqueConstraint(columnNames = "EMAIL") })  
  22. public class EmployeeEntity implements Serializable  
  23. {  
  24.     private static final long serialVersionUID = -1798070786993154676L;  
  25.   
  26.     @Id  
  27.     @GeneratedValue(strategy = GenerationType.IDENTITY)  
  28.     @Column(name = "ID", unique = true, nullable = false)  
  29.     private Integer employeeId;  
  30.   
  31.     @Column(name = "EMAIL", unique = true, nullable = false, length = 100)  
  32.     private String email;  
  33.   
  34.     @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)  
  35.     private String firstName;  
  36.   
  37.     @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)  
  38.     private String lastName;  
  39.   
  40.     @OneToMany(cascade=CascadeType.ALL)  
  41.     @JoinTable(name="EMPLOYEE_ACCOUNT", joinColumns={@JoinColumn(name="EMPLOYEE_ID", referencedColumnName="ID")}  
  42.     , inverseJoinColumns={@JoinColumn(name="ACCOUNT_ID", referencedColumnName="ID")})  
  43.     private Set<AccountEntity> accounts;  
  44.   
  45.     public Integer getEmployeeId() {  
  46.         return employeeId;  
  47.     }  
  48.   
  49.     public void setEmployeeId(Integer employeeId) {  
  50.         this.employeeId = employeeId;  
  51.     }  
  52.   
  53.     public String getEmail() {  
  54.         return email;  
  55.     }  
  56.   
  57.     public void setEmail(String email) {  
  58.         this.email = email;  
  59.     }  
  60.   
  61.     public String getFirstName() {  
  62.         return firstName;  
  63.     }  
  64.   
  65.     public void setFirstName(String firstName) {  
  66.         this.firstName = firstName;  
  67.     }  
  68.   
  69.     public String getLastName() {  
  70.         return lastName;  
  71.     }  
  72.   
  73.     public void setLastName(String lastName) {  
  74.         this.lastName = lastName;  
  75.     }  
  76.   
  77.     public Set<AccountEntity> getAccounts() {  
  78.         return accounts;  
  79.     }  
  80.   
  81.     public void setAccounts(Set<AccountEntity> accounts) {  
  82.         this.accounts = accounts;  
  83.     }  
  84. }  

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

在配置文件中配置实体,我们已经有了两个在运行时的实体,我们必须在配置文件中增加他们。请注意只有一个集合实体可以在配置文件中配置,否则会有意外的情况发生
  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.   
    3. import hibernate.test.HibernateUtil;  
    4. import hibernate.test.oneToMany.joinTable.AccountEntity;  
    5. import hibernate.test.oneToMany.joinTable.EmployeeEntity;  
    6.   
    7. import java.util.HashSet;  
    8. import java.util.Set;  
    9.   
    10. import org.hibernate.Session;  
    11.   
    12. public class TestJoinTable  
    13. {  
    14.     public static void main(String[] args)  
    15.     {  
    16.         Session session = HibernateUtil.getSessionFactory().openSession();  
    17.         session.beginTransaction();  
    18.   
    19.         AccountEntity account1 = new AccountEntity();  
    20.         account1.setAccountNumber("123-345-65454");  
    21.   
    22.         AccountEntity account2 = new AccountEntity();  
    23.         account2.setAccountNumber("123-345-6542222");  
    24.   
    25.         //Add new Employee object  
    26.         EmployeeEntity emp = new EmployeeEntity();  
    27.         emp.setEmail("demo-user@mail.com");  
    28.         emp.setFirstName("demo");  
    29.         emp.setLastName("user");  
    30.   
    31.         Set<AccountEntity> accounts = new HashSet<AccountEntity>();  
    32.         accounts.add(account1);  
    33.         accounts.add(account2);  
    34.   
    35.         emp.setAccounts(accounts);  
    36.         //Save Employee  
    37.         session.save(emp);  
    38.   
    39.         session.getTransaction().commit();  
    40.         HibernateUtil.shutdown();  
    41.     }  
    42. }  
    43.   
    44. Output:  
    45.   
    46. Hibernate: insert into Employee (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)  
    47. Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)  
    48. Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)  
    49. Hibernate: insert into EMPLOYEE_ACCOUNT (EMPLOYEE_ID, ACCOUNT_ID) values (?, ?)  
    50. Hibernate: insert into EMPLOYEE_ACCOUNT (EMPLOYEE_ID, ACCOUNT_ID) values (?, ?) 
posted @ 2017-10-09 11:23  MrMrCash  阅读(228)  评论(0编辑  收藏  举报