【问题标题】:Perform a query in Spring Data JPA using an Example to get only the First Projection使用示例在 Spring Data JPA 中执行查询以仅获取第一个投影
【发布时间】:2018-03-23 01:34:05
【问题描述】:

在 Spring Data 中,我有一个 Projection 来获取我的 Entity 中的 Id

public interface IdOnly<T> {
    T getId();
}

我需要按多个字段过滤我的查询,其中许多字段可以为 null,并且不应在查询中使用 null 值。所以,我打算使用Query by Example 来完成这项工作。除此之外,我只需要第一个 IDlimiting the query on database。但不幸的是,似乎没有办法做到这一点。

// It works
IdOnly<Long> findFirstBy();

// It works too (although it does not limit the query in database)
Entity findOne(Example<Entity> example);

// It doesn't work. Throws an ClassCastException when returns a non-null entity
IdOnly<Long> findOne(Example<Entity> example);

// That's the one I really need
// The server doesn't start (IndexOutOfBoundsException)
IdOnly<Long> findFirstBy(Example<Entity> example);

那么,有没有办法使用示例进行这样的查询,以仅获取第一个投影?

Projections

Query by Example

Limiting query results

【问题讨论】:

    标签: java spring spring-data spring-data-jpa


    【解决方案1】:

    我真的无法使用所有三个 Spring 设施来做到这一点。因此,我更喜欢使用Example,因为有大量代码可以测试所有字段并获取谓词。这样一来,使用Query By Example 的易用性就可以更轻松地进行不同的查询。

    import static org.springframework.data.jpa.convert.QueryByExamplePredicateBuilder.getPredicate;
    
    @Service
    public class EntityService {
    
        @PersistenceContext
        private EntityManager em;
    
        public Long findFirstById(Entity entity) {
            return getId(em, Entity_.id, Example.of(entity), Entity.class, Long.class);
        }
    
        private static <E, N> N getId(EntityManager em, SingularAttribute<E, N> id, Example<E> example, Class<E> entityClass, Class<N> idClass) {
            final CriteriaBuilder cb = em.getCriteriaBuilder();
            final CriteriaQuery<N> cq = cb.createQuery(idClass);
            final Root<E> from = cq.from(entityClass);
            cq.select(from.get(id)).where(getPredicate(from, cb, example));
            return em.createQuery(cq).setMaxResults(1).getResultList().stream().findFirst().orElse(null);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-09
      • 2021-06-01
      • 2019-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-02
      • 1970-01-01
      相关资源
      最近更新 更多