`

【翻译】CriteriaBuilder and Dynamic Queries in JPA 2.0

阅读更多
A major new feature of Java EE 6 is JPA 2.0 and in particular the addition of the Criteria API which provides the ability to dynamically construct object-based queries.

This resolves some of the problems which arise when building dynamic native queries. The below example shows how to find customer entities with two search parameters:

public List<CustomerEntity> findCustomers(
    final String firstName, final String surname) {

    StringBuilder queryBuilder = new StringBuilder(
        "select c from Customer where ");
    List<String> paramList = new ArrayList<String>();
    paramList.add(" upper(c.firstName) like '%?%'"
        .replace("?", firstName.toUpperCase()));
    paramList.add(" upper(c.surname) like '%?%'"
        .replace("?", surname.toUpperCase()));

    Iterator itr = paramList.iterator();
    while(itr.hasNext()) {
        queryBuilder.append(itr.next());
        if (itr.hasNext()) {
            queryBuilder.append(" and ");
        }
    }

    final Query query = entityManager.createNativeQuery(
        queryBuilder.toString());

    List<Object> resultList = (List<Object>)query.getResultList();

    // iterate, cast, populate and return a list
}


The problem with the above is that it is not type safe and involves iterating over a List of Object where those Objects are themselves Object arrays. Also should Customer contain any child elements, these would have to be retrieved in a separate call.

Using the CriteriaBuilder, the same results can be achieved as shown below:

public List<CustomerEntity> findCustomers(final String firstName, final String surname) {

    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<CustomerEntity> query = 
        builder.createQuery(CustomerEntity.class);
    Root<CustomerEntity> cust = query.from(CustomerEntity.class);
    query.select(cust);

    List<Predicate> predicateList = new ArrayList<Predicate>();

    Predicate firstNamePredicate, surnamePredicate;

    if ((firstName != null) && (!(firstName.isEmpty()))) {
        firstNamePredicate = builder.like(
            builder.upper(cust.<String>get("firstName")), 
                       "%"+firstName.toUpperCase()+"%");
        predicateList.add(firstNamePredicate);
    }

    if ((surname != null) && (!(surname.isEmpty()))) {
        surnamePredicate = builder.like(
        builder.upper(cust.<String>get("surname")),
            "%"+surname.toUpperCase()+"%");
        predicateList.add(surnamePredicate);
    }

    Predicate[] predicates = new  
        Predicate[predicateList.size()];
    PredicateList.toArray(predicates);
    query.where(predicates);

    return entityManager.createQuery(query).getResultList();
} 


There is some type safety in the above but it can be furthered tied down by using the metamodel class for the entity, by using the metamodel class's public static members instead of text strings for the entity's attributes. The code would now look like this:

firstNamePredicate = builder.like(
        builder.upper(cust.get(CustomerEntity_.firstName)),
            "%"+firstName.toUpperCase()+"%");
 
    surnamePredicate = builder.like(
        builder.upper(cust.get(CustomerEntity_.surname)),
            "%"+surname.toUpperCase()+"%"); 


Having built metamodel classes using Maven, it's questionable whether it's a worthwhile exercise as any mistakes in the text based approach to finding attribute names should be flagged up by comprehensive unti testing.
分享到:
评论

相关推荐

    JPA 2.0jar包及JPA2.0源代码

    **Java持久化API (JPA) 2.0 深入解析** Java持久化API (Java Persistence API),简称JPA,是Java平台上的一个标准,用于管理关系数据库中的对象。JPA 2.0是其第二个主要版本,带来了许多增强特性和改进,旨在简化...

    JPA2.0高级教程

    ### JPA2.0 高级教程知识点概览 #### 一、JPA2.0简介与特性 **Java Persistence API (JPA)** 是一种用于处理数据库操作的标准接口,为Java开发人员提供了一种对象关系映射(ORM)机制。JPA2.0作为JPA的一个重大...

    jpa2.0 英文手册

    - jpa2.0:这是JPA 2.0规范的简写标签,常用于搜索和分类相关文档和资源。 - 英文:强调了文档的语言版本是英文。 - 手册:通常指的是一份详尽的指导书,包含理论讲解、操作指南以及实例演示等。 - jsr317:与描述中...

    jpa2.0 规范文档.zip

    Java persistence api, jpa 2.0最终版使用规范, 资源是压缩包, 下载后解压缩文件,然后重命名persistence-2_0-final-spec文件,添加后缀 .pdf 原始文件的类型时pdf的

    jpa2.0jar包

    **Java Persistence API (JPA) 2.0 Jar 包** Java Persistence API 是Java平台上的一个标准接口,用于处理对象关系映射(ORM),它允许Java开发者以面向对象的方式操作数据库,而无需直接编写SQL语句。JPA 2.0是这...

    Spring Data JPA 2.0 标准模板

    **Spring Data JPA 2.0 标准模板详解** Spring Data JPA 是 Spring 框架的一个子项目,它简化了数据访问层的开发,提供了对 Java Persistence API(JPA)的高度抽象和自动化。在 Spring Data JPA 2.0 版本中,它...

    jpa 2.0 jar 包 下载

    jpa 2.0 jar 包 下载 jpa 2.0 jar 包 下载 jpa 2.0 jar 包 下载

    spring3.0.5与JPA2.0(hibernate3.6)的集成详细说明

    本篇将详细讲解如何将Spring 3.0.5与JPA 2.0(基于Hibernate 3.6)进行集成,以构建高效、灵活的应用程序。 首先,让我们了解Spring 3.0.5的核心特性。Spring 3.0引入了若干改进和新特性,包括对JSR-303(Bean ...

    一.初识JPA2.0

    初识JPA 2.0** Java Persistence API (JPA) 是Java平台上的一个标准,用于处理对象关系映射(ORM),它允许Java开发者将对象模型与关系数据库进行交互。JPA 2.0是这个标准的一个重要版本,引入了许多新特性和改进...

    openjpa2.0英文版API

    ### OpenJPA 2.0 英文版 API 相关知识点 #### 一、简介与背景 **OpenJPA 2.0** 是一款基于 Java Persistence API (JPA) 的开源持久层框架,用于实现对象关系映射(ORM)。它提供了一种标准化的方式将 Java 对象与...

    JPA2.0 javax.persistence src 源码

    JPA 2.0是该规范的一个重要版本,它在JPA 1.0的基础上引入了许多增强功能,提高了开发人员的生产力和数据库操作的灵活性。`javax.persistence`包是JPA的核心API,包含了一系列接口和注解,用于定义实体、查询语言...

    JPA2.0-Spring2.x-Struts2注解

    主要讲述JPA2.0规范,Struct2 Spring注解等技术

    JSF1.2+JPA2.0+Spring3.1整合开发

    **JSF 1.2 + JPA 2.0 + Spring 3.1 整合开发详解** 在Java企业级应用开发中,JSF(JavaServer Faces)、JPA(Java Persistence API)和Spring框架的结合使用是常见的技术栈。本文将深入探讨如何将这三个组件整合在...

    hibernate-jpa-2.0-api-1.0.1.Final-sources.jar

    hibernate-jpa-2.0-api-1.0.1.Final-sources.jar hibernate jpa 源代码

    Spring3+Struts2+JPA2.0

    标题 "Spring3+Struts2+JPA2.0" 提到的是一个经典的Java企业级应用开发框架组合,主要用于构建高效、可维护性高的Web应用程序。这个组合将Spring的依赖注入和事务管理、Struts2的MVC架构以及JPA(Java Persistence ...

    JPA2.0(hibernate-3.5.2实现)jar文件整理上传

    antlr-2.7.6.jar, cglib-2.2.jar, commons-collections-3.1.jar, ...hibernate-jpa-2.0-api-1.0.0.Final.jar, javassist-3.9.0.GA.jar, jta-1.1.jar, slf4j-api-1.6.1.jar, slf4j-log4j12-1.6.1.jar

    jpa2.0(JSR-317) 规范 包含javadoc

    该草案获得JSR-317专家组全部通过 新增了大量的特性包括类型安全的动态查询(Criteria API );加入了大量必须的 ORM 映射增强特性;标准的二级缓存,标准的 JDBC ... 目前hibernate 3.5 已经提供了jpa2.0的全部实现;

    hibernate-jpa-2.0-api-1.0.1.Final.jar

    hibernate-jpa-2.0-api-1.0.1.Final.jar

    jpa 2.0 lock機制介紹1

    **JPA 2.0 锁机制介绍** Java Persistence API(JPA)是Java平台上的一个标准,用于处理对象关系映射(ORM),使开发者能够将数据库操作与业务逻辑更紧密地结合。在多线程和并发环境中,数据一致性与安全性至关重要...

    spring-dynamic-jpa:Spring Dynamic JPA将使使用JpaRepository轻松实现动态查询成为可能

    弹簧动力jpa Spring Dynamic JPA将使使用JpaRepository轻松实现动态查询变得容易。如何使用? 添加依赖implementation ' ... Spring启动版spring-dynamic-jpa版本2.0.x.发布2.0.3 2.1.x.发布2.1.3

Global site tag (gtag.js) - Google Analytics