创建没有实体的Spring存储库

时间:2019-04-04 10:35:09

标签: java spring

我想使用spring数据存储库接口执行本机查询-由于复杂度低,我认为这种方法最简单。

但是当扩展接口ex时。 CrudRepository<T, ID>我需要写T-我的实体,该实体不可用。

我的本​​机查询不返回任何具体实体,那么在没有实体的情况下创建spring存储库的最佳方法是什么?

6 个答案:

答案 0 :(得分:4)

当前,JPA中没有创建仅包含本机甚至JPQL查询(使用@Query表示法)的存储库的功能。为了解决这个问题,您可以创建一个虚拟对象,将其插入扩展接口,如下所示:

@Entity
public class RootEntity {
    @Id
    private Integer id;
}

@Repository
public interface Repository extends JpaRepository<RootEntity, Integer> {
}

答案 1 :(得分:3)

这对我们有用。查看实体管理器

https://www.baeldung.com/hibernate-entitymanager

@Repository
public class MyRepository {

    @PersistenceContext
    EntityManager entityManager;

    public void doSomeQuery(){
        Query query = entityManager.createNativeQuery("SELECT foo FROM bar");
        query.getResultsList()
        ...
    }

}

顺便说一句,我认为这里甚至不需要@Repository 注释..

答案 2 :(得分:0)

CrudRepositoryJpaRepository不能在没有<Entity,ID>对的情况下工作。

最好创建一个自定义存储库,注入EntityManager并从那里查询:

  @Repository
  public class CustomNativeRepositoryImpl implements CustomNativeRepository {

    @Autowired
    private EntityManager entityManager;

    @Override
    public Object runNativeQuery() {
        entityManager.createNativeQuery("myNativeQuery")
         .getSingleResult();
    }
}

答案 3 :(得分:0)

您可以仅使用@Repository注释您的实现,并获取EntityManager的实例。

public interface ProductFilterRepository {
    Page<Product> filter(FilterTO filter, Pageable pageable);
}



@Repository
@AllArgsConstructor
public class ProductFilterRepositoryImpl implements ProductFilterRepository {

    private final EntityManager em;

    @Override
    public Page<Product> filter(FilterTO filter, Pageable pageable) {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Product> cq = cb.createQuery(Product.class);
        Root<Product> root = cq.from(Product.class);
        List<Predicate> predicates = new ArrayList<>();

        if (filter.getPriceMin() != null) {
            predicates.add(cb.ge(root.get("price"), filter.getPriceMin()));
        }
        if (filter.getPriceMax() != null) {
            predicates.add(cb.le(root.get("price"), filter.getPriceMax()));
        }
        if (filter.getBrands() != null && !filter.getBrands().isEmpty()) {
            predicates.add(root.get("brand").in(filter.getBrands()));
        }
        if (filter.getCategories() != null && !filter.getCategories().isEmpty()) {
            predicates.add(root.get("category").in(filter.getCategories()));
        }
        cq.where(predicates.toArray(new Predicate[0]));
        TypedQuery<Product> tq = em.createQuery(cq);
        tq.setMaxResults(pageable.getPageSize());
        tq.setFirstResult(pageable.getPageNumber() * pageable.getPageSize());

        CriteriaQuery<Long> countCq = cb.createQuery(Long.class);
        countCq.select(cb.count(countCq.from(Product.class)));
        countCq.where(predicates.toArray(new Predicate[0]));
        TypedQuery<Long> countTq = em.createQuery(countCq);
        Long count = countTq.getSingleResult();

        return new PageImpl<>(tq.getResultList(), pageable, count);
    }
}

答案 4 :(得分:0)

如果您使用的是JPA,则需要实体。作为先前的答案,您可以创建NativeQueries或直接从EntityManager中使用Criteria API。

一些有关自定义报告和常见回购行为的文档:

https://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html#repositories.custom-behaviour-for-all-repositories

答案 5 :(得分:0)

我认为当您没有本机查询结果集的具体实体类时,可以考虑使用JdbcTemplate。使用JdbcTemplate查询数据时,结果集需要一个POJO类,而POJO类需要一个实现RowMapper接口的映射器。