jpa 创建不带实体的Spring资源库

flvlnr44  于 2022-11-14  发布在  Spring
关注(0)|答案(6)|浏览(197)

我想使用spring数据仓库接口来执行原生查询--我认为这种方式是最简单的,因为复杂度低。
但是当扩展接口ex.CrudRepository<T, ID>时,我需要写T -我的实体,这是不可用的。
我的原生查询不返回任何具体的实体,那么创建没有实体的Spring存储库的最佳方法是什么?

4c8rllxm

4c8rllxm1#

CrudRepositoryJpaRepository在设计上不能在没有<Entity,ID>对的情况下工作。
您最好创建一个自定义的存储库,从那里注入EntityManager和查询:

@Repository
  public class CustomNativeRepositoryImpl implements CustomNativeRepository {

    @Autowired
    private EntityManager entityManager;

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

ki1q1bka2#

目前,JPA中还没有创建仅使用原生或JPQL/HQL查询(使用@Query表示法)的存储库的功能。要解决这个问题,可以创建一个伪对象插入到扩展接口中,如下所示:

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

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

7fhtutme3#

这适用于我们。请参见实体管理器
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()
        ...
    }

}
vql8enpb

vql8enpb4#

您只需使用@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);
    }
}
jq6vz3qz

jq6vz3qz5#

我认为,当您没有用于本地查询的结果集的具体实体类时,可以考虑使用JdbcTemplate作为替代方法。使用JdbcTemplate查询数据需要用于结果集的POJO类和实现POJO类的RowMapper接口的Map器。

f8rj6qna

f8rj6qna6#

如果您正在使用JPA,则需要实体。与前面的答案一样,您可以直接从EntityManager创建NativeQueries或使用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

相关问题