写点什么

Hades——JPA 的开源实现

  • 2011-02-07
  • 本文字数:3979 字

    阅读完需:约 13 分钟

简介

几乎每个应用系统都需要通过访问数据来完成工作。要想使用领域设计方法,你就需要为实体类定义和构建资源库来实现领域对象的持久化。目前开发人员经常使用 JPA 来实现持久化库。JPA 让持久化变得非常容易,但是仍然需要编写很多模板代码。Hades 是一个开源库,基于 JPA 和 Spring 构建,通过减少开发工作量显著的改进了数据访问层的实现。本文是 Hades 的向导性教程,会带你走进 Hades 的世界,帮助你了解 Hades 在数据持久化方面能为你做些什么,并简要介绍了最新的 2.0 版本的新特性。

Hades 的核心部分由通用的持久化库实现构成,不仅提供了基本的 CRUD(增删改读)方法,而且增加了一些通用场景功能的实现,类似分页这样的功能你就不用自己实现了。还包括查询实体页、动态增加排序定义等能力。

查询

查询是使用最多的数据访问操作,如果你了解了 Hades,就会意识到查询作为 Hades 的核心功能之一,定义和执行查询是多么容易,大大减少了工作量。一般完成一个查询操作包括以下三个步骤:

  1. 增加特定实体的库接口
  2. 增加查询方法
  3. 微调查询

首先你需要声明一个继承了 GenericDao<Entity, Id> 的接口,该类保证在 Hades 接口中定义的 CRUD 方法在你的接口中是有效的,如下:

复制代码
public interface UserRepository extends GenericDao<User, Long> { … }

其次是根据业务需求为你的接口增加查询方法:

复制代码
List findByUsername(String username);

这又会引出问题,那就是如何实现查询方法。如果你没有增加任何附加的元数据,Hades 会尝试查找格式为{entity}. {method-name}的 JPA 查询方法,如果有效的话就使用该方法。如果没有找到任何可以解析的方法名,那就会创建一个查询方法。因此,之前的例子就会产生这样一样查询:select u from User u where u.username=?。查询解析支持更多的关键字,你可以随时在参考手册文档中找到它们。

如果想定义手工查询,你可以使用 Hades 的 @Query 注释功能,让该查询直接在方法中执行:

复制代码
@Query("select from User u where u.lastname = ?");
List someReallyStrangeName(String lastname);

这样你可以自由的进行方法命名,既可以对查询定义实现完全控制,又不必担心那些查询模板代码。围绕着执行查询还有很多方式,例如使用分页查询、执行编辑查询等

引导 Hades

到目前为止我们已经讨论了如何创建带有查询方法的库接口,接下来我们看一下如何使用这些接口。首先创建实体类的实例,然后根据该实例创建 GenericDaoFactory 的实例,通过工厂实例的 getDao 方法创建你需要的资源库,如下代码所示:

复制代码
EntityManager em = … // Get access to EntityManager
GenericDaoFactory factory = GenericDaoFactory.create(em);
UserRepository userRepository = factory.getDao(UserRepository.class);

由于资源库经常通过依赖注入的方式被其客户端持有,所以 Hades 提供了优雅的方式与与 Spring 应用集成。在 Spring 的应用中引导 Hades 非常简单,只需使用 Hades 的命名空间,并声明可以被匹配到的基础包即可:

复制代码
<hades:dao-config base-package="com.acme.*.repository" />

以上配置方式会选中所有继承了 GenericDao 的资源库接口,并为每个接口创建 Spring 的 Bean。当然,命名空间支持更细粒度的配置,以实现精确控制。Hades 的 Eclipse 插件实现了与 Spring IDE 和 SpringSource 工具套件的无缝集成,这样你就可以从其它 Bean 引用 Hades 的资源库,并在你的工作空间把它们标记为 Spring 的 Bean。想了解详细信息请查看其参考手册。

审计

在系统中记录实体类的创建者、修改者和相关日期等信息是一个很常见的需求。Hades 提供了监听器 EntityListener,可以帮你透明的实现这些功能。要启用 Hades 的审计功能,只需要在 orm.xml 文件中定义 AuditingEntityListener 即可:

复制代码
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class="org.synyx.hades.domain.auditing.support.AuditingEntityListener" />
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>

并在 Spring 的配置中启动审计功能,如下:

复制代码
<hades:auditing auditor-aware-ref="auditorAware" />

auditorAware 是引用的 Spring Bean,需要实现 AuditorAware 接口,通常是实现针对当前用户的安全查询功能。如果你只想跟踪创建和编辑日期,只需忽略该属性即可。想了解更多审计特性,请参考相关文档

JPA 2.0 和事务性资源库

Hades2.0 是基于 JPA2.0 以及相关的 Hibernate、EclipseLink 和 OpenJPA 版本构建的。基于该版本的 CRUD 事务操作使用非常简单,开箱即用,对于相对简单的场景基本不需要再进行事务性的封装。未来结合资源库接口可以让事务管理变得更加简单。

复制代码
public interface UserRepository extends GenericDao<User, Long> {
@Transactional(readOnly = true);
List<User> findByUsername();
@Override
@Transactional(readOnly = true, timeout = 60);
List<User> readAll();
}

正如你看到的,你可以简单的通过为查询方法增加注释 @Transactional 的方式把它们加入事务。当然,也可以不用注释的方式,基于 XML 的事务配置也能运行的很好。在 GenericDao 中的 CRUD 操作具备默认的事务性(对只读操作来说就是把 readOnly 设置为 true)。如果你想为这些方法重新配置事务,简单的为这些方法声明自定义的 @Transactional 即可实现。想了解更多详细信息,请参考事务相关的参考文档。

规范

Hades 最新版本的一个非常酷的特性是基于 GenericDao 的扩展即可符合规范。这里提到的规范指领域驱动设计的概念,DDD 是由 Eric Evans 和 Martin Fowler 首次提出,从本质上捕捉实体的业务规则的一种开发方法。Hades 提供的抽象方式可以很容易的基于 JPA2.0 的标准 API 实现领域驱动设计。在这里我们假设你已经读过上面提到的两位作者写的 DDD 相关的书籍。Hades 提供了如下方式定义规范:

复制代码
class BookSpecifications {
public Specification<Book> hasAuthorWithFirstnameLike(final String firstname) {
return new Specification<Book>() {
public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
return cb.like(root.join("author").get("firstname"), firstname);
}
}
}
public Specification<Book> hasGenre(final Genre genre) {
return new Specification<Book>() {
public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
return cb.equal(root.get( "genre"), genre);
}
}
}
}

当然,这并不是最优雅的代码片段(如果未来与 Java 8 里的单抽象方法(SAM)特性结果结合的话,效果会更好)。从积极的方面考虑,我们在资源库层面获得了执行规范的可能性:

复制代码
bookRepository.readAll(hasAuthorWithFirstnameLike("Oliv*"));

好了,我们在声明式查询方面已经做了很多,不是吗?规范的能力真正闪光的时候是把它们整合为新的规范的时候。Hades 提供了规范助手类,可以进行任意的合并:

复制代码
bookRepository.readAll(where(hasAuthorWithFirstnameLike( "Oliv*").or(hasGenre(Genres.IT)));

通过这种方式,扩展资源库就变成了只是增加新的规范。少量的规范就可以帮助你使用类似 DSL 的柔性 API 查询资源库,而不是针对每次外部查询请求都使用查询方法访问资源库。想了解更多详细信息,请参考相关文档

扩展

2.0 版本的另一部分内容是扩展模块,可以实现 Hades 与展现层技术框架(例如 Spring 的 MVC)的无缝集成。它提供了属性编辑器和 Spring 3.0 转换器,可以透明的把实体类与 MVC 控制器方法的绑定在一起,同时 MVC 扩展还可以动态的从 HTTP 请求中提取分页信息。一个展示用户列表的页面,在控制层的写法就是这样:

复制代码
@Controllerclass UserController {
@Autowired
UserRepository userRepository;
@RequestMapping("/users")
public void showUsers(Pageable pageable, Model model) {
model.addAttribute("users", userRepository.readAll(pageable));
}
@RequestMapping("/users/{id}")
public String showUser(@PathVariable("id") User user, Model model) {
model.addAttribute("user", user);
return"user";
}
}

就像你看到的,showUsers 方法不需要解析 HttpServletRequest 获取分页信息。另外请注意,在 showUser(…) 方法中绑定的 id 路径变量的参数已经是实体类了。由于 Spring MVC 基础框架的配置内容已经超出了本文要讨论的范围,如果想了解更多信息,请参考扩展模块配置信息的相关章节,其中提供了非常容易的设置样例

下一步?

展望未来,2.1.x 版本之后,Hades 可能会成为 Spring Data 项目的一部分,其核心将作为实现其它数据存储资源库的实现基础。Spring Data 是 SpringSource 的项目,其目标是为新兴的数据库、特定的数据存储提供 Spring 的方言支持,包括 NoSQL 数据库。

总结

Hades 大大简化了使用 JPA 执行数据层的访问过程。你可以自由的进行精确的 CRUD 操作、执行查询和规范等。Hades 既可以独立使用,可以方便的集成到 Spring 中。除此之外,Eclipse 的插件 Spring IDE/STS 和附加的 Spring Roo 都可以非常容易的创建资源库。想了解更多信息,请参考项目网站

关于作者

Oliver Gierke 是 VMware 公司的 SpringSource 部门的高级顾问,是 Hades 开源项目的项目主管。大约在两年前他在原公司 Synyx 启动了该项目。

查看英文原文: Hades - JPA Repositories Done Right


给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中 与我们的编辑和其他读者朋友交流。

2011-02-07 00:005623

评论

发布
暂无评论
发现更多内容

Unlock the Future of Connectivity: Explore Dual-Band Dual-Concurrent (DBDC) Cards for Industrial Applications

wallyslilly

MT7915

Allavsoft for Mac(优秀的视频下载工具)

Mac相关知识分享

LeetCode题解:2665. 计数器 II

Lee Chen

指标平台为业务部门提供实时、准确的数据支持,以助力业务决策

Aloudata

数据分析 指标管理 指标平台 指标开发

连续七年亮相进博会,高通携手合作伙伴共赢智能计算新时代

业界

TikTok直播有什么要求?

Ogcloud

TikTok tiktok运营 tiktok直播 tiktok直播专线 tiktok直播网络

Hadoop优化|全面调优攻略 | HDFS、MapReduce、YARN性能提升秘诀 | 专家实战分享!

敏捷调度TASKCTL

hadoop hdfs YARN MapReduce服务

数据虚拟化技术揭秘:如何整合多样数据源及其独特优势

Aloudata

数据分析 数据开发 数据集成 数据编织 数据虚拟化技术

高通中国区董事长孟樸:5G与AI的融合正加速企业数字化转型步伐

新消费日报

Eudic欧路词典 for Mac(英语词典翻译查询工具)

Mac相关知识分享

Microsoft Remote Desktop Beta for Mac(微软远程连接工具)

Mac相关知识分享

指标平台帮助企业在业务运营过程中快速定位和解决业务问题

Aloudata

数据仓库 数据分析 指标管理 指标平台 指标开发

《深入浅出Apache Spark》系列③:Spark SQL解析层优化策略与案例解析

数新网络官方账号

sql 大数据

【教程】第二章:设计任务管理系统 —— 胸有成竹,步步为营

NocoBase

开源 低代码 教程 无代码

Zabbix 和 Prometheus 选型对比

巴辉特

Prometheus zabbix

Navicat Premium 15 for Mac强大数据库管理软件

Mac相关知识分享

Termius for mac(终端模拟器/SSH/SFTP客户端)

Mac相关知识分享

SecureCRT for mac强大的终端 SSH 仿真工具

Mac相关知识分享

SpringBoot必须掌握的常用注解!

王磊

万字长文2024最全Go面经汇总

王中阳Go

Go 面经 大厂

无代码MES是什么?MES系统包含什么功能?

积木链小链

无代码 无代码平台 无代码MES

AE2025视频后期优化处理:After Effects 2025 for mac 激活版

你的猪会飞吗

mac软件下载 Mac破解软件 AE2025破解版

前端三件套配合豆包MarsCode 实现钉钉官网动画

豆包MarsCode

程序员 AI 钉钉 开发

SmoothScroll for mac(鼠标增强工具)激活版

Mac相关知识分享

为什么建议不要使用TikTok共享节点?

Ogcloud

TikTok tiktok运营 TikTok养号 tiktok矩阵 tiktok网络

高性能日志结构化引擎 — GreptimeDB Piepline 设计与实现技术揭秘

Greptime 格睿科技

时序数据库 日志储存 日志引擎

数据分散在不同的业务线,如何对全域数据做高效整合和集成?

Aloudata

数据仓库 数据分析 商业分析 noetl

SmartSVN for Mac(SVN客户端)

Mac相关知识分享

DeFi 4.0峥嵘初现:主权金融时代的来临

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 公链开发 代币开发

枫清科技高雪峰:从大模型到行业智能体的智能转型之路

Fabarta

大模型 #人工智能

TG机器人链游开发项目:迈向去中心化游戏新时代

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 公链开发 代币开发

Hades——JPA的开源实现_Java_Oliver Gierke_InfoQ精选文章