在 Java EE应用程序中使用JPQL

翻译 2017年09月29日 10:28:10

     如果您使用过数据库,您很可能已经使用过 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 的相应方法,执行以下一般步骤:

  1. 使用注入或通过 EntityManagerFactory 实例显式获取一个 EntityManager 实例。
  2. 通过调用相应 EntityManager 的方法(如 createQuery),创建一个 Query 实例。
  3. 如果有查询参数,使用相应 Query 的 setParameter 方法进行设置。
  4. 如果需要,使用 setMaxResults 和/或 setFirstResult Query 的方法设置要检索的实例的最大数量和/或指定检索的起始实例位置。
  5. 如果需要,使用 setHint Query 的方法设置供应商特定的提示。
  6. 如果需要,使用 setFlushMode Query 的方法设置查询执行的刷新模式,覆盖实体管理器的刷新模式。
  7. 使用相应 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<Customer> arr_cust = (List<Customer>)em.createQuery("SELECT c FROM Customer c")
                              .getResultList(); 
        out.println("List of all customers: "+"<br/>");
Iterator i = arr_cust.iterator();
Customer cust;
while (i.hasNext()) {
cust = (Customer) i.next();
out.println(cust.getCust_id()+"<br/>");
out.println(cust.getCust_name()+"<br/>");
out.println(cust.getEmail()+"<br/>");
out.println(cust.getPhone()+"<br/>");
out.println("----------------" + "<br/>");
        }
...

  当然,这里让人关注的是 EntityManager 实例的 createQuery 方法和 Query 实例的 getResultList 方法。EntityManager 的 createQuery 用于创建 Query 实例,然后该实例的 getResultList 方法用于执行作为参数传递给 createQuery 的 JPQL 查询。正如您可能已经猜到的那样,Query 的 getResultList 方法以 List 形式返回查询的结果,在这个特定示例中,将 List 的元素转换为 Customer 类型。

如果您需要检索单个结果,Query API 接口提供了 getSingleResult 方法,如以下示例所示。然而,请注意,如果您返回多个结果,使用 getSingleResult 将引发异常。

        该示例还说明了如何使用 Query 的 setParameter 方法,通过该方法,您可以将参数值绑定到某个查询参数。使用 setParameter,您既可以绑定命名参数也可以绑定位置参数。但是,您在此处绑定的是一个命名参数。

...
        Integer cust_id =2;
        Customer cust = (Customer)em.createQuery("SELECT c FROM Customer c WHERE c.cust_id=:cust_id")
                              .setParameter("cust_id", cust_id)
                              .getSingleResult(); 
        out.println("Customer with id "+cust.getCust_id()+" is: "+ cust.getCust_name()+"<br/>");
...
值得注意的是,如果检索单个实体实例,SELECT JPQL 语句并不是唯一的选择。您还可以使用 EntityManager 的 find 方法,通过该方法,您可以根据实体的 ID(作为参数传入)检索单个实体实例。

在某些情况下,您可能只需检索目标实体实例中的某些信息,针对特定的实体字段定义 JPQL 查询。如果您只需检索此处查询的 Customer 实体实例的 cust_name 字段的值,上面的代码片段应改为:

...
        Integer cust_id =2;
        String cust_name = (String)em.createQuery("SELECT c.cust_name FROM Customer c WHERE c.cust_id=:cust_id")
                              .setParameter("cust_id", cust_id)
                              .getSingleResult(); 
        out.println("Customer with id "+cust_id+" is: "+cust_name+"<br/>");
...
同样,要获取客户名称的完整列表,可以使用以下代码:
...
        List<String> arr_cust_name = (List<String>)em.createQuery("SELECT c.cust_name FROM Customer c")
                              .getResultList(); 
        out.println("List of all customers: "+"<br/>");
Iterator i = arr_cust_name.iterator();
String cust_name;
while (i.hasNext()) {
cust_name = (String) i.next();
out.println(cust_name+"<br/>");
        }
...
重新再看 SQL,您可能想起 SQL 查询的选择列表可以由 FROM 子句中指定的表中的若干个字段组成。在 JPQL 中,您还可以使用组成的选择列表,仅从感兴趣的实体字段中选择数据。但是,在这种情况下,您需要创建一个类,将查询结果赋予该类。

  在下一小节中,您将看到一个 JPQL 联接查询的示例,该查询的选择列表由源自多个实体的字段组成。

JPQL查询语句(Java Presistence Query Language)(转)

JPQL查询语句(Java Presistence Query Language)(转) 博客分类:  JPA   1.Query createQuery(String qlS...
  • evilcry2012
  • evilcry2012
  • 2015-09-06 18:53:52
  • 977

【java EE】JPQL

JPQL全称Java Persistence Query Language 基于首次在EJB2.0中引入的EJB查询语言(EJB QL),Java持久化查询语言(JPQL)是一种可移植的查询语言...
  • jing18033612052
  • jing18033612052
  • 2017-09-17 21:36:08
  • 132

JPQL的使用

JPQL的使用规则
  • spring123tt
  • spring123tt
  • 2011-03-31 19:07:00
  • 2660

Java EE 组件 容器 服务器

Java EE 组件 容器 服务器 一、组件(Component): 组件可以定义为一种自治的、提供外部公共接口的、动态可用的事物处理过程,组件可以用来构建其它组件或者应用...
  • u012033124
  • u012033124
  • 2016-11-15 16:07:40
  • 455

JPA学习(五):java持久化查询语言JPQL--动态查询的使用及语法限制

JPQL动态查询(模糊查询)中 通配符 与 动态变量 的 联合使用 限制:JPQL动态查询 参数不存在问题解决:错误使用方式=>形如如下代码:1/2:@SuppressWarnings("unchec...
  • timo1160139211
  • timo1160139211
  • 2017-02-21 10:49:47
  • 1320

Java EE应用程序的组件构成与EJB 的出现

1、Java EE应用程序的组件构成(分布式多层应用架构)   Java EE应用程序由组件构成:      客户端组件与运行在服务器端的业务逻辑组件通信时,既可以直接访问,也可以通过Web层...
  • wang379275614
  • wang379275614
  • 2015-01-31 11:12:38
  • 1450

Java EE容器

Java EE容器对于开发人员需要引入复杂的代码解决事务以及状态管理问题,处理多线程、资源的调度等待底层细节,很多业务逻辑可以封装在可重用的组件中去,此外,Java EE为每一种组件都提供了基于容器的...
  • dingji_ping
  • dingji_ping
  • 2016-08-24 20:46:51
  • 1276

Java EE 应用项目的设计分层模型

开始初学Java EE,因为需要进行前后端的维护,配合上Android的应用展示。开始新的征程。本篇文章是更偏于学习笔记,查考书籍有两本《轻量级Java EE》、《精通J2EE》。肯定会有些不严谨。目...
  • vaecer
  • vaecer
  • 2015-03-15 00:32:34
  • 1463

关于JPQL中的in的用法 指教?

目前使用Maven管理  Spring-Jpa 做的项目。在dao层使用的jpql查询  @Query(value="from ContractProduct where contract.id i...
  • qq_41507845
  • qq_41507845
  • 2018-01-06 19:50:38
  • 122

JAVAEE 之web服务器应用程序Tmocat 和web应用程序的目录结构

Tomcat是使用java语言开发web应用的时候常用的服务器应用程序,是Apache开源组织提供的免费开源软件。   Tomcat的目录结构:    bin--存放tomcat启动关闭所用的批...
  • a907231810
  • a907231810
  • 2013-05-03 20:37:31
  • 581
收藏助手
不良信息举报
您举报文章:在 Java EE应用程序中使用JPQL
举报原因:
原因补充:

(最多只允许输入30个字)