jpa 原生sql 查询返回一个实体_使用 JPQL 和原生 SQL 查询 JPA 实体

示例应用程序

本文讨论的代码段摘自本文随附的示例应用程序中使用的 Java 源文件。浏览一下示例存档,您可能会注意到,这是一个基于 Java Servlet 和 Java 持久性 API 技术的简单 Web 应用程序。为简单起见,它不使用企业 bean,而是直接从 servlet 内部发出 JPQL 查询。但是,这并不意味着您将不能在企业 bean 中利用这里讨论的 JPQL 查询 — 您可以在任何 Java EE 组件中定义 JPQL 查询。

图 1 显示了示例实体结构。如您所见,它包含一组通过不同类型的关系彼此关联的实体。为了说明本文后面的“定义 JPQL 联接”部分中讨论的 JPQL 连接查询的用法,需要这样一个分支结构。

图 1 示例应用程序中使用的实体之间的关系

图 1 示例应用程序中使用的实体之间的关系

要详细了解如何设置和启动示例应用程序,可以参考示例存档根目录下的 readme.txt 文件。

在 Java EE 应用程序中使用 JPQL

如果您使用过数据库,您很可能已经使用过 SQL,这个标准的工具提供了一系列语句,用于访问和操作关系数据库中的信息。实际上,JPQL 和 SQL 有很多相似之处。归根结底,它们都用于访问和操作数据库数据。而且,二者都使用非过程语句 — 通过特殊解释程序识别的命令。此外,JPQL 在语法上与 SQL 也相似。

JPQL 和 SQL 的主要区别在于,前者处理 JPA 实体,后者直接处理关系数据。作为 Java 开发人员,您可能还有兴趣了解使用 JPQL 与 SQL/JDBC 的不同,无需在 Java 代码中使用 JDBC API — 容器在幕后为您完成了所有这些工作。

通过 JPQL,您可以使用 SELECT、UPDATE 或 DELETE 这三条语句之一来定义查询。值得注意的是,EntityManager API 接口提供的方法也可用于对实体执行检索、更新和删除操作。具体来说,是 find、merge 和 remove 方法。然而,这些方法的使用通常限于单个实体实例,当然,级联生效时除外。而 JPQL 语句则没有这样的限制 — 您可以定义对若干组实体进行批量更新和删除操作,并定义查询返回若干组实体实例。

要从 Java 代码内发出 JPQL 查询,您需要利用 EntityManager API 和 Query API 的相应方法,执行以下一般步骤:

使用注入或通过 EntityManagerFactory 实例显式获取一个 EntityManager 实例。

通过调用相应 EntityManager 的方法(如 createQuery),创建一个 Query 实例。

如果有查询参数,使用相应 Query 的 setParameter 方法进行设置。

如果需要,使用 setMaxResults 和/或 setFirstResult Query 的方法设置要检索的实例的最大数量和/或指定检索的起始实例位置。

如果需要,使用 setHint Query 的方法设置供应商特定的提示。

如果需要,使用 setFlushMode Query 的方法设置查询执行的刷新模式,覆盖实体管理器的刷新模式。

使用相应 Query 的方法 getSingleResult 或 getResultList 执行查询。可是,如果进行更新或删除操作,您必须使用 executeUpdate 方法,它返回已更新或删除的实体实例的数量。

EntityManager 接口方法以及 Query API 接口方法的完整列表可以在以下 Enterprise JavaBeans 3.0 规范中找到:Java 持久性 API 文档(JSR-220 的一部分)。

既然您已经对如何创建以及发出 JPQL 查询有了大致了解,您可能希望看一些实际的示例。以下代码片段摘自一个 servlet 的 doGet 方法,该方法使用 JPQL 查询获取有关与查询中指定的 Customer 实体相关的底层关系表中存储的所有客户的信息。

...

@PersistenceUnit

private EntityManagerFactory emf;

public void doGet(

...

EntityManager em = emf.createEntityManager();

PrintWriter out = response.getWriter();

List arr_cust = (List)em.createQuery("SELECT c FROM Customer c")

.getResultList();

out.println("List of all customers: "+"
");

Iterator i = arr_cust.iterator();

Customer cust;

while (i.hasNext()) {

cust = (Customer) i.next();

out.println(cust.getCust_id()+"
");

out.println(cust.getCust_name()+"
");

out.println(cust.getEmail()+"
");

out.println(cust.getPhone()+"
");

out.println("----------------" + "
");

}

...

当然,这里让人关注的是 EntityManager 实例的 createQuery 方法和 Query 实例的 getResultList 方法。EntityManager 的 createQuery 用于创建 Query 实例,然后该实例的 getResultList 方法用于执行作为参数传递给 createQuery 的 JPQL 查询。正如您可能已经猜

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值