source

엔티티 없이 스프링 저장소 생성

manysource 2023. 2. 22. 22:38

엔티티 없이 스프링 저장소 생성

스프링 데이터 저장소 인터페이스를 사용하여 네이티브 쿼리를 실행하고 싶습니다.복잡도가 낮기 때문에 이 방법이 가장 간단하다고 생각합니다.

단, 인터페이스 ex를 확장하는 경우. CrudRepository<T, ID>T - my entity라고 적어야 하는데 사용할 수 없습니다.

네이티브 쿼리는 구체적인 엔티티를 반환하지 않습니다.엔티티 없이 스프링 저장소를 만드는 가장 좋은 방법은 무엇입니까?

CrudRepository또는JpaRepository기능하도록 설계되어 있지 않다<Entity,ID>짝.

커스텀 레포 작성 후 Entity Manager를 삽입하고 쿼리하는 것이 좋습니다.

  @Repository
  public class CustomNativeRepositoryImpl implements CustomNativeRepository {

    @Autowired
    private EntityManager entityManager;

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

현재 JPA에는 네이티브 쿼리 또는 JPQL/HQL 쿼리(@Query 표기법 사용)만으로 리포지토리를 만드는 기능은 없습니다.이를 회피하려면 다음과 같이 확장 인터페이스에 삽입할 더미 개체를 만듭니다.

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

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

우리한테는 잘된 일이야엔티티 매니저 참조

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엔티티 매니저 인스턴스를 가져옵니다.

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);
    }
}

네이티브 쿼리의 결과 세트에 대한 구체적인 엔티티 클래스가 없는 경우 JdbcTemplate 사용을 대안으로 고려할 수 있습니다.JdbcTemplate를 사용하여 데이터를 쿼리하려면 결과 세트에 대해 POJO 클래스와 POJO 클래스에 대해 RowMapper 인터페이스를 구현하는 매퍼가 필요합니다.

JPA를 사용하는 경우 엔티티가 필요합니다.이전 답변과 마찬가지로 NativeQueries를 작성하거나 EntityManager에서 직접 Criteria API를 사용할 수 있습니다.

커스텀 리포트 및 일반적인 repo 동작에 관한 문서:

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

언급URL : https://stackoverflow.com/questions/55513776/create-spring-repository-without-entity