我想知道我是否可以在自定义查询中使用JPA规范谓词?
我已经尝试但没有成功。
我们说我有一个实体Customer
和一个存储库:
@Repository
public interface CustomerRepository
extends JpaRepository<Customer, Long>,
JpaSpecificationExecutor<Customer> {
}
这样查询是好的
@Query("select c from Customer c")
Stream<Customer> streamAllCustomers();
这不行
Stream<Customer> streamAllCustomersWithFilter(Specification<Customer> filter);
有没有办法实现这个目标?
NB我知道我可以在@Query
中添加参数但是我想留在当前应用程序的设计中并一直使用规范。
答案 0 :(得分:1)
<强> TL; DR; 强>
不,不,但手动是
我认为issue DATAJPA-906可以回答您的两个问题
你没有,至少不是以直接支持的方式:
在JpaSpecificationExecutor上支持Java 8 Streams
[..]
遗憾的是,由于方法签名中的Stream会在Java&lt;版本的Java上呈现无法加载的接口,因此必须等待2.0版本。 8。
当然,您可以随时add your custom methods including implementation。
@Query
注释定义的查询您如何组合通过规范定义的CriteriaQuery和手动定义的JPQL查询?
如果问题不明确:如果您的自定义查询包含内部选择,那么规范中的条件应该如何?
你能做什么
实现自定义方法,返回Stream并将规范作为参数,将其与准备好的规范相结合,以调用JpaSpecificationExecutor
接口的现有方法并将结果转换为Stream
答案 1 :(得分:0)
有一种方法可以从我使用的Spring Data JPA中流式传输数据。 由于整个查询结果不会加载到内存中,因此该方法在处理大量数据的同时避免了高内存消耗,非常有用。
通过以下实现创建custom individual repository
public class YourCustomRepositoryImpl implements YourCustomRepository {
@PersistenceContext(unitName = "yorEntityManagerFactory")
private EntityManager em;
@Override
public Stream<SomeEntity> streamAll(Specification<SomeEntity> spec) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<SomeEntity> query = cb.createQuery(SomeEntity.class);
Root<SomeEntity> root = query.from(SomeEntity.class);
query.where(spec.toPredicate(root, query, cb));
return em.createQuery(query).getResultStream();
}
}
当然,这需要JPA 2.2支持ORM框架(我使用了Hibernate 5.3)。
此外,您还应注意在处理流时提供连接以保持活动状态。