JPA对象嵌套是指在JPA实体中嵌套另一个JPA实体,以便在一个实体中存储另一个实体的信息。这种嵌套关系可以用来表示多对一(Many-to-One)或者一对多(One-to-Many)的关系。
JPA对象嵌套有助于减少数据库表的数量,并使得数据库表之间的关系更加清晰。此外,使用JPA对象嵌套还可以减少代码量,因为不需要再创建新的实体来表示关联关系。
@Entity public class Person { @Id private Long id; private String name; @OneToOne(cascade = CascadeType.ALL) private Address address; // getters and setters... }
@Entity public class Address { @Id private Long id; private String street; private String city; // getters and setters... }
以下代码显示如何在一对多映射中使用嵌入式键。
下面的代码来自Department.java。
package cn..common; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.MapKey; import javax.persistence.OneToMany; @Entity public class Department { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; private String name; @OneToMany(mappedBy="department") private Map<EmployeeName, Employee> employeesByName; public Department() { employeesByName = new HashMap<EmployeeName,Employee>(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String deptName) { this.name = deptName; } public Map<EmployeeName, Employee> getEmployees() { return employeesByName; } public void addEmployee(Employee employee) { EmployeeName empName = new EmployeeName(); empName.setFirst_Name(employee.getFirstName()); empName.setLast_Name(employee.getLastName()); employeesByName.put(empName, employee); if (employee.getDepartment() != null) { employee.getDepartment().removeEmployee(employee); } employee.setDepartment(this); } public void removeEmployee(Employee employee) { Iterator iter = employeesByName.entrySet().iterator(); while (iter.hasNext()) { Employee current = ((Map.Entry<EmployeeName,Employee>) iter.next()).getValue(); if (current.getId() == employee.getId()) { iter.remove(); current.setDepartment(null); } } } public String toString() { StringBuffer aBuffer = new StringBuffer("Department "); aBuffer.append(" id: "); aBuffer.append(id); aBuffer.append(" name: "); aBuffer.append(name); aBuffer.append(" employeeCount: "); aBuffer.append(employeesByName.size()); return aBuffer.toString(); } }
以下代码来自Employee.java。
package cn..common; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToOne; @Entity public class Employee { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; @Column(name="F_NAME") private String firstName; @Column(name="L_NAME") private String lastName; private long salary; @ManyToOne private Department department; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public long getSalary() { return salary; } public void setSalary(long salary) { this.salary = salary; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } public String toString() { StringBuffer aBuffer = new StringBuffer("Employee "); aBuffer.append(" id: "); aBuffer.append(id); aBuffer.append(" name: "); aBuffer.append(lastName); aBuffer.append(", "); aBuffer.append(firstName); aBuffer.append(" with dept: "); if(null != department) { aBuffer.append(department.getName()); } return aBuffer.toString(); } }
下面的代码来自PersonDaoImpl.java。
package cn..common; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.springframework.transaction.annotation.Transactional; @Transactional public class PersonDaoImpl { public void test() { Employee e = new Employee(); e.setFirstName("Tom"); Department d = new Department(); d.setName("test"); e.setDepartment(d); EmployeeName name = new EmployeeName(); name.setFirst_Name("Tom"); d.getEmployees().put(name, e); em.persist(e); em.persist(d); } @PersistenceContext private EntityManager em; }
以下代码来自EmployeeName.java。
package cn..common; import javax.persistence.Column; import javax.persistence.Embeddable; @Embeddable public class EmployeeName { @Column(name="F_NAME", insertable=false, updatable=false) private String first_Name; @Column(name="L_NAME", insertable=false, updatable=false) private String last_Name; public String getFirst_Name() { return first_Name; } public void setFirst_Name(String firstName) { first_Name = firstName; } public String getLast_Name() { return last_Name; } public void setLast_Name(String lastName) { last_Name = lastName; } }下载 Embeddable_KeyMapping.zip
以下是数据库转储。
Table Name: DEPARTMENT Row: Column Name: ID, Column Type: INTEGER: Column Value: 1 Column Name: NAME, Column Type: VARCHAR: Column Value: test Table Name: EMPLOYEE Row: Column Name: ID, Column Type: INTEGER: Column Value: 1 Column Name: F_NAME, Column Type: VARCHAR: Column Value: Tom Column Name: L_NAME, Column Type: VARCHAR: Column Value: null Column Name: SALARY, Column Type: BIGINT: Column Value: 0 Column Name: DEPARTMENT_ID, Column Type: INTEGER: Column Value: 1
JPA教程 -JPA一对一连接列示例以下部分显示如何在JPA中为一对一映射设置连接列。我们使用 @JoinColumn 注释设置连接列。@OneToOn...
JPA教程 -JPA 多对多映射示例以下代码显示如何创建多对多映射。它描述了人与部门之间的关系。一个部门可以有很多人,一个人可以...
JPA教程 -JPA 单向一对多映射示例以下代码显示了如何进行单向一对多映射。例子下面的代码来自PersonDaoImpl.java。package cn..c...
JPA教程 -JPA命名查询参数类型示例在命名查询中,我们还可以添加参数。@Entity@NamedQueries({@NamedQuery(name=findEmployeesAb...