`
mondayw
  • 浏览: 143703 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

[译文]JPA的实施模式:检索实体

阅读更多

原文:JPA implementation patterns: Retrieving entities

作者:Vincent Partington

出处:http://blog.xebia.com/2009/04/03/jpa-implementation-patterns-retrieving-entities/

 

 

上周我们谈论了如何保存实体,而且一旦保存了实体,我们也就希望能够检索它。与管理双向关联和保存实体相比,检索实体实在是相当的简单,如此简单以至于我都怀疑在写本篇博客时能够有多少可说的要点。不过,我们在编写本文中的代码时确实是用到了一些很好的模式,而且我很有兴趣听到那些你用来检索实体的模式,所以,让我们从这里开始JPA实施模式系列中的下一节内容。

基本上,JPA有两种检索实体的方法:

Ÿ           EntityManager.find根据实体的id来查找实体,当实体不存在时,返回null

Ÿ           如果把使用Java持久查询语言(Java Persistence Query Language)指定的查询串传给EntityManager.createQuery的话,那么它会返回一个实体列表或者单个实体。

 

Query对象也可以通过引用命名查询(使用EntityManager.createNamedQuery)来创建,或者是传入SQL查询(使用三个各具特色的EntityManager.createNativeQuery中的一个)。而且与其名字暗含的意思不一,Query也可以用来执行更新或者删除语句。

命名查询可能看起来像是一种保持查询与其所查询的实体之间关系的很好的方式,不过我发现这种方式并不是特别有效。大多数的查询需要使用Query.setParameter的各种不同形式来设置参数,把查询和设置参数的代码放在一起能够使得这两者更易于理解,这就是为什么我在DAO中把它们放在一起并避免使用命名查询的原因。

我发现的一种有用的约定是区分对待查找(finding)实体和获取(getting)实体的处理,在前一种情况下,当实体没能被找到时返回null,而在后一种情况下则是抛出异常。在代码预期出现实体的地方使用后一种方法来防止随后会出现NullPointerExceptions被弹出的情况。

 

通过id查找和获取单个实体

 

在前面几篇博客之一中我们曾讨论过的JpaDao基础类的这一模式的一个实现,其看上去类似这样(为了对比,其中包括了查找方法):

 

public E findById(K id) {

return entityManager.find(entityClass, id);

}

 

public E getById(K id) throws EntityNotFoundException {

E entity = entityManager.find(entityClass, id);

if (entity == null) {

           throw new EntityNotFoundException(

                    "Entity " + entityClass.getName() + " with id " + id + " not found");

}

return entity;

}

当然还需要把这一新的方法添加到Dao接口中:

 

E getById(K id);

 

使用查询来查找和获取单个实体

 

在使用查询来查找单个实体时,可以做出类似的区分,以下的findOrderSubmittedAt方法在查询未能找到实体时返回nullgetOrderSubmittedAt方法则抛出NoResultException异常。如果有一个以上的结果返回的话,以上两种方法都会抛出NonUniqueResultException异常。为了保持getOrderSubmittedAt方法与findById方法之间的一致,可以把NoResultException映射成EntityNotFoundException,不过既然两者都是非受查的异常,所以这不是一定需要做的。

由于这些方法只适用于Order对象,那么JpaOrderDao中的一部分就是这样的:

 

public Order findOrderSubmittedAt(Date date) throws NonUniqueResultException {

Query q = entityManager.createQuery(

           "SELECT e FROM " + entityClass.getName() + " e WHERE date = :date_at");

q.setParameter("date_at", date);

try {

           return (Order) q.getSingleResult();

} catch (NoResultException exc) {

           return null;

}

}

 

public Order getOrderSubmittedAt(Date date) throws NoResultException, NonUniqueResultException {

Query q = entityManager.createQuery(

           "SELECT e FROM " + entityClass.getName() + " e WHERE date = :date_at");

q.setParameter("date_at", date);

return (Order) q.getSingleResult();

}

 

把正确的方法添加到OrderDao接口中的工作就作为练习留给读者来完成好了。

 

使用查询来查找多个实体

 

当然我们也希望能够查找多个实体,在这种情况下,我发现在获取(getting)和查找(finding)之间不用做出什么区分,findOrdersSubmittedSince方法仅是返回被找到的实体的一个列表,该列表可以是包含零个、一个或者多个实体,参见下面的代码:

 

public List<Order> findOrdersSubmittedSince(Date date) {

Query q = entityManager.createQuery(

                    "SELECT e FROM " + entityClass.getName() + " e WHERE date >= :date_since");

q.setParameter("date_since", date);

return (List<Order>) q.getResultList();

}

 

有眼力的读者会注意到,该方法已经在JpaOrderDao的第一个版本中出现过了。

 

因此,虽然检索实体的工作很简单,但在实现fander方法和getter方法时还是有些模式可依据的,当然,我很有兴趣了解你在代码中是如何处理这些情况的。

 

附:JPA 1.0还不支持,不过JPA2.0会包括一个Criteria APICriteria API允许动态地建立JPA查询,Criteria查询比串查询更灵活,可以根据搜索表单的输入来建立它们,并且因为是使用领域对象来定义它们,所以它们作为到领域对象的引用,可以被自动重构,更易于维护。遗憾的是,Criteria API需要通过名称来引用实体的属性,所以在重新命名属性时,IDE不会起到帮助作用。

 

分享到:
评论

相关推荐

    Spring Data JPA系列5:让IDEA自动帮你写JPA实体定义代码.doc

    此外,IDEA还提供了自动生成JPA实体类的功能,这对于创建与数据库表对应的实体模型非常方便。通过"File -&gt; Project Structure -&gt; Modules -&gt; JPA"的路径设置JPA支持,选择Hibernate作为默认提供者。然后,在...

    jpa入门案例:单表查询,包括分页查询 使用springboot来整合实现

    接着,创建一个实体类,例如名为`User`,并使用`@Entity`注解标记该类为数据库表对应的实体。然后,使用`@Id`注解指定主键字段,以及可能的`@Table`注解指定表名。此外,还可以使用`@Column`注解来定义字段与数据库...

    Spring Data JPA系列2:SpringBoot集成JPA详细教程,快速在项目中熟练使用JPA.doc

    这些注解可以用来指定扫描的表映射实体 Entity 的目录、表 repository 目录、开启 JPA 审核能力等。 在 application.properties 文件中,可以配置一些数据库连接信息,例如数据库 URL、用户名、密码等。同时,也...

    Spring Data JPA系列3:JPA项目中核心场景与进阶用法介绍.doc

    在处理关联关系时,Spring Data JPA提供了懒加载和急加载(Eager vs Lazy Fetching)机制,通过配置实体类的属性映射,可以在需要时按需加载关联的数据,避免了N+1查询问题。同时,它还支持级联操作(Cascade ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1

    一共有三个分卷。全部下载才能解压。 这本书不错,值得一看。

    blueprints-jpa-graph:蓝图 API 在 JPA 上的实现

    1:JPA: : 2:对象数据库: ://www.objectdb.com/ 3:JPA 性能基准: ://www.jpab.org/All/All/All.html 支持功能 支持所有蓝图功能, 除外 支撑 支持 支持 Java 5、6 或 7 支持 JPA 你需要哪一个取决于你想用...

    notes_JPA_JSF:使用JSF和JPA实施来重建Notes项目

    【标题】"notes_JPA_JSF:使用JSF和JPA实施来重建Notes项目"涉及的是在Java开发环境中,利用JavaServer Faces (JSF) 和 Java Persistence API (JPA) 技术重构建一个名为Notes的项目。JSF是Java EE平台上的一个用户...

    spring-data-jpa-extra:带有模板动态查询的spring数据jpa(例如

    春天数据jpa额外使用jpa的spring数据更舒适我爱spring-data-jpa,她放开我的双手,粗鲁的方法很无聊! 然而,尽管她为我们提供了规范解决方案,但她在动态本机查询上并不完美,而且她的返回类型必须是一个实体,但是...

    spring-data-jpa-demo:这是一个Spring Data JPA的demo,重点演示大多数常用的使用方法

    Spring Data Jpa常用功能演示配套说明请查看:项目简介本项目采用当前最新版本的2.1.4.RELEASE做基础架构支撑,请参考本项目建议有一定的基础及经验。教程主要针对中文用户,如果您英文良好,建议直接阅读官网帮助...

    JPA学习笔记-EJB-05JPA实体对象状态和实体对象的高级操作

    ### JPA实体对象状态 #### 一、实体对象的状态分类 在Java Persistence API (JPA) 中,实体对象的状态管理是实现数据持久化的基础之一。根据实体对象与实体管理器(EntityManager)之间的交互关系,实体对象可以...

    JPA学习源码(EJB实体Bean)

    **JPA学习源码(EJB实体Bean)** Java Persistence API(JPA)是Java平台上的一个标准,用于管理和持久化对象。它简化了在关系数据库中存储和检索Java对象的过程,是JAVA EE5中引入的重要组件。JPA通过提供ORM(对象...

    JPA操作手册,包括EJB3.0

    - **OpenJPA/JPA**:实体映射主要通过注解来实现,如 `@Entity`、`@Table` 等,同时也支持使用 `persistence.xml` 文件来进行配置。 **6. 分离实体** - **Hibernate**:支持一级缓存和二级缓存,可以有效地提高...

    JPA技术:年初写的办公室OA系统

    1. **实体(Entity)**: 在JPA中,实体代表数据库表中的记录,通常是一个Java类,通过`@Entity`注解标识。实体类的属性对应于表的列。 2. **实体管理器(EntityManager)**: 是JPA的主要接口,负责处理数据库的CRUD...

    优秀实践分享 Spring Data JPA2

    本文是介绍Spring-data-jpa的PPT的学习笔记,整理了Spring Data JPA相关知识配置和实践源码. 本文介绍知识点有: JPA与Spring的相关配置 JPA 方法名常用查询 JPA 使用@Query注解实现JPQL和本地自定义查询 JPA API 条件...

    JPA标注推荐圈子: Database圈子

    JPA 提供了一种简单的方法来存储和检索应用程序中的数据。通过使用注解或 XML 描述对象-关系映射元数据,开发人员可以轻松地将 Java 对象与数据库表关联起来。 在本篇内容中,我们将深入探讨 JPA 注解的一些核心...

    jpa 别名转实体

    别名转实体是JPA中的一个概念,它涉及到如何通过别名来查询数据库并映射到对应的实体类上。 在JPA中,我们经常需要处理SQL查询结果,这些结果可能包含别名,例如在HQL(Hibernate Query Language)或JPQL(Java ...

Global site tag (gtag.js) - Google Analytics