我想使用spring数据仓库接口来执行原生查询--我认为这种方式是最简单的,因为复杂度低。但是当扩展接口ex.CrudRepository<T, ID>时,我需要写T -我的实体,这是不可用的。我的原生查询不返回任何具体的实体,那么创建没有实体的Spring存储库的最佳方法是什么?
CrudRepository<T, ID>
4c8rllxm1#
CrudRepository或JpaRepository在设计上不能在没有<Entity,ID>对的情况下工作。您最好创建一个自定义的存储库,从那里注入EntityManager和查询:
CrudRepository
JpaRepository
<Entity,ID>
@Repository public class CustomNativeRepositoryImpl implements CustomNativeRepository { @Autowired private EntityManager entityManager; @Override public Object runNativeQuery() { entityManager.createNativeQuery("myNativeQuery") .getSingleResult(); } }
ki1q1bka2#
目前,JPA中还没有创建仅使用原生或JPQL/HQL查询(使用@Query表示法)的存储库的功能。要解决这个问题,可以创建一个伪对象插入到扩展接口中,如下所示:
@Entity public class RootEntity { @Id private Integer id; } @Repository public interface Repository extends JpaRepository<RootEntity, Integer> { }
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() ... } }
vql8enpb4#
您只需使用@Repository对实现进行注解,并获得EntityManager的示例。
@Repository
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); } }
jq6vz3qz5#
我认为,当您没有用于本地查询的结果集的具体实体类时,可以考虑使用JdbcTemplate作为替代方法。使用JdbcTemplate查询数据需要用于结果集的POJO类和实现POJO类的RowMapper接口的Map器。
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
6条答案
按热度按时间4c8rllxm1#
CrudRepository
或JpaRepository
在设计上不能在没有<Entity,ID>
对的情况下工作。您最好创建一个自定义的存储库,从那里注入EntityManager和查询:
ki1q1bka2#
目前,JPA中还没有创建仅使用原生或JPQL/HQL查询(使用@Query表示法)的存储库的功能。要解决这个问题,可以创建一个伪对象插入到扩展接口中,如下所示:
7fhtutme3#
这适用于我们。请参见实体管理器
https://www.baeldung.com/hibernate-entitymanager
vql8enpb4#
您只需使用
@Repository
对实现进行注解,并获得EntityManager的示例。jq6vz3qz5#
我认为,当您没有用于本地查询的结果集的具体实体类时,可以考虑使用JdbcTemplate作为替代方法。使用JdbcTemplate查询数据需要用于结果集的POJO类和实现POJO类的RowMapper接口的Map器。
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