使用 JPA 检索多个对象

Posted

技术标签:

【中文标题】使用 JPA 检索多个对象【英文标题】:Retrieve multiple objects using JPA 【发布时间】:2015-12-22 18:05:34 【问题描述】:

在使用普通 JDBC 几个月后,我最近切换到 JPA (EclipseLink),并且正在使用 API 重建我的一个应用程序。

快速背景:我在 mysql 数据库中有两个表。 CandidateBean 表示的表使用其主键作为 SearchCriteria 表中“Ref”列中的外键。

我想以这样一种方式检索对象,即如果我检索 CandidateBean,它会自动检索它链接到的 SearchCriteria 对象。我了解单个实体和 JPQL 查询的检索,但我很确定在 JPA 中有一种直接的方法可以做到这一点,它不像 JDBC 那样涉及多个查询/连接。

我有以下代码:

CandidateBean:

// Tells JPA that this class defines an entity to be stored in a database
@Entity
// Overrides default table name
@Table(name = "CandidateUsers")
// Maps CandidateProfile table to this entity
public class CandidateBean implements Serializable 

private static final long serialVersionUID = 1L;

// Overriding column names to match database tables
@Column(name = "FName")
private String fName;
@Column(name = "LName")
private String lName;
@Column(name = "Pass")
private String password;
@Column(name = "Email")
private String email;
// Tells JPA that the following field is the primary key for this entity
@Id
// Tells JPA to use auto-incremented values of the MySQL table as the userID
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "UserID")
private int userID = 0;
etc etc constructors/getters/setters

搜索条件:

//Tells JPA that this class defines an entity to be stored in a database
@Entity
//Overrides default table name
@Table(name = "SearchCriteria")
public class SearchCriteria implements Serializable 

private static final long serialVersionUID = 1L;

// Tells JPA that the following field is the primary key for this entity
@Id
// Tells JPA to use auto-incremented values of the MySQL table as the userID
@GeneratedValue(strategy = GenerationType.IDENTITY)
// Overriding column names to match database tables
@Column(name = "SearchID")
private int searchID;
@Column(name = "State")
private String state;
@Column(name = "Field")
private String field;
@Column(name = "Cert")
private String certification;
@Column(name = "CompDate")
private String date;
@Column(name = "School")
private String school;

@ManyToOne(optional = false)
@JoinColumn(name="Ref", referencedColumnName = "UserID")
private CandidateBean user;
etc etc constructors/getters/setters

如果我需要澄清一些事情,请告诉我。感谢您的帮助!

【问题讨论】:

【参考方案1】:

正如 Dhruv Rai Puri 所提到的,JPA 允许您使用 OneToMany 映射将 SearchCriteria 的集合关联到 CandidateBean,如下所述: https://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Mapping/Relationship_Mappings/Collection_Mappings/OneToMany

对于您的模型,它很简单:

  @ManyToOne(mappedBy = "user")
  List<SearchCriteria> searchCriterias;

请注意,mappedBy 指的是 SearchCriteria 中用户属性的映射,因此将使用此处指定的连接列。它使关系是双向的,并由“用户”控制;无论 CandidateBean 中的集合是否发生变化,对 SearchCriteria 中“用户”的更改都会更改数据库中的字段,但出于缓存目的,两者应保持同步。上面的映射默认为惰性获取,这意味着如果关联实例尚未缓存在对象中,它将在访问时触发对关联实例的查询。

从那里,您可以控制通过各种 JPA 和本机 EclipseLink 设置检索此集合的方式和时间 - 您可以设置始终以某种方式获取关系,或者决定逐个查询更改它。看 http://vard-lokkur.blogspot.com/2011/05/eclipselink-jpa-queries-optimization.html

【讨论】:

这澄清了一切,我非常感谢详细的回复。干杯【参考方案2】:

就像您在 SearchCriteria 中放置了一个 @ManyToOne,在 CandidateBean 中放置一个反向的 @OneToMany,这将是一个 SearchCriterias 的列表/集。现在,当您获取 CandidateBean 的记录时,您将自动获得链接的 SearchCriterias。您可以根据需要以 LAZY 或 EAGER 方式获取链接记录。

另外也不需要单独的 JOIN 等,@OneToMany 映射就足够了

【讨论】:

以上是关于使用 JPA 检索多个对象的主要内容,如果未能解决你的问题,请参考以下文章

JPA 使用指南 /Eclipselink/JPA 实体生成器

JPA Annotations - 如何检索具有特定列值的所有实体

无法使用 JPA 查询检索结果

在 oracle JPA () 中检索光标

如何使用 JPA 和 Hibernate 通过自定义对象实体属性进行查询

使用 CriteriaBuilder 的 JPA 计数(*)。如何使用 CriteriaBuilder 检索 count(*) 列