jpa java
在本系列文章的第一部分中 ,我们讨论了如何将流行的Spring数据库轻松地装配到其他标准Java EE环境中。 Spring Data自动生成最常用的DAO方法,在简单的情况下,您实际上可以轻松地使用自定义查询扩展它,而无需编写任何JPQL查询或接触JPA API。
DeltaSpike Data在纯CDI容器中像半自动生成的数据存储库一样实现Spring Data。 尽管它不像Spring Data那样成熟和广泛使用,但是两者之间最大的区别似乎在于质量教程和示例的数量。 有些事情还没有Spring Data那样流畅,这当然可能是由于我现有的Spring Data经验,但是DeltaSpike还具有一些独特的便捷功能,我也希望在Spring Data中看到这些功能。
与我们在前一篇文章中为SpringData引入的ContactRepository类似,其中一个查询使用命名约定实现,如下所示:
@Repository(forEntity = Contact.class)
public interface ContactRepository extends EntityRepository<Contact, Long> {
public List<Contact> findByCompany(Company company);
}
DeltaSpike数据旨在使用普通CDI容器工作。 当我们针对现代Java EE环境时,我们将利用容器管理的持久性上下文和JTA事务。 与使用Spring Data一样,一种简单而安全的方法是在自动生成的存储库类之前使用无状态EJB。 与Spring Data类似,我们需要发布用于CDI托管bean的EntityManager,并且需要说明如何处理事务。
发布用于CDI bean的EntityManager与Spring Data完全一样。 在我们的示例应用程序中 ,相同的CdiConfig类实际上将其发布到两个库中。 要指示DeltaSpike Data避免调用JPA低级事务管理API,请将以下配置添加到src / main / resources / META-INF / apache-deltaspike.properties
globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy =
org.apache.deltaspike.jpa.impl.transaction.ContainerManagedTransactionStrategy
设置完成后,您准备创建与SpringData类似的EJB。 实现几乎是相同的,只是删除方法更改为删除,但是如果仍然不确定要使用哪个库或从一个库切换到另一个库,则可以在DAO级别隐藏该事实。
@Stateless
public class ContactFacade {
@Inject
ContactRepository repository;
public Contact save(Contact entity) {
return repository.save(entity);
}
public void delete(Contact entity) {
repository.remove(entity);
//repository.delete(entity);
}
public List<Contact> findAll() {
return repository.findAll();
}
如果您有使用Spring Data的经验,您会发现在更高级的用法上存在一些差异。 将较大的表绑定到UI时,您会注意到第一个,您需要对数据库进行分页查询。 在Spring Data中,这通常是通过传递Pageable参数来完成的,该参数包含有关排序的详细信息以及应返回哪种类型的结果子集。
使用DeltaSpike数据,您可以添加起始索引和最大结果数作为参数,并使用@FirstResult和@MaxResults对其进行注释。 通过将查询方法的返回类型声明为QueryResult而不是基本List,也可以实现相同的目的。 QueryResult是一个中间结果,尚未实际执行查询,但可以为它定义详细信息,例如排序和如何限制结果集。 与Spring中的Pageable有点不同,但是几乎可以实现相同的事情。 我个人认为哪个更好。
在某些情况下,当基于命名约定进行自动查询时,Spring Data仍然会感觉更聪明。 例如,我无法让countByInvoicerAndNameLike函数起作用,尽管它在Spring Data中很好用。 不过,可以通过将其编写为findBy样式查询并使用QueryResult作为返回类型来解决。 然后,DAO中的count方法可能如下所示:
public long countContacts(Invoicer invoicer, String filter) {
return repository.findByInvoicerAndNameLike(invoicer, filter.toUpperCase() + "%")
.count();
}
我面临的另一个棘手的部分是在创建不区分大小写的LIKE查询时,您几乎总是想要搜索UI。 使用Spring Data,您可以简单地在方法名称后附加“ IgnoreCase”,所有字符串属性都将按您期望的方式处理。 在撰写本文时,我向DeltaSpike的Jira提出了一个问题,并且DeltaSpike被证明是一个真正活跃的OS项目:该功能仅在几天后才出现在git存储库中。 从1.3.0开始,您可以对DeltaSpike Data使用相同的IgnoreCase关键字。
大多数ORM实现都具有专有的API,用于“按示例查询”样式的编程。 但是,最近,许多开发人员在尝试使用纯JPA API时都忽略了它们。
DeltaSpike数据通过示例样式API包含一个不错的与实现无关的查询,该API自动为所有生成的存储库类提供。 还有LIKE查询版本,其默认值很好:'%'字符自动添加到字符串,并且忽略大小写。 使用此api编写上述过滤用例将如下所示:
public List<Contact> findPaged(Company company, String filter, int first, int max) {
Contact contact = new Contact();
contact.setCompany(company);
contact.setName(filter);
return repository.findByLike(contact, firstResult, maxResults,
Contact_.invoicer, Contact_.name);
}
通过示例样式查询进行查询可能会增加您的LoC,但是对于面向对象的开发人员而言,可读性非常好。
DeltaSpike Data还提供了类似DSL的API来创建JPA 2 Criteria查询。 这是对基本JPA标准API的不错的改进,但是我将跳过更详细的讨论。 原因是我还没有弄清楚为什么要使用它而不是QueryDSL提供的编程查询,我将在本系列文章的最后一部分中进行更多讨论。
另请参阅: JPA生产力提升器#1:Spring数据
jpa java