2012-12-02 5 views
5

나는 두 기관이 있습니다Spring Data에서 "집계 함수에 의한 정렬"을 만드는 방법은 무엇입니까?

ResourceFile :

@Entity 
@Table(name = "resource_file") 
public class ResourceFile extends IdEntity<Integer> { 

    @Id 
    @SequenceGenerator(name = "resource_file_id_generator", sequenceName = "resource_file_id", allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "resource_file_id_generator") 
    @Column(name = "id", unique = true, nullable = false) 
    @Nonnegative 
    private Integer id; 

    ... 
} 

FavoriteResourceFile :

@Entity 
@Table(name = "favorite_resource_file") 
@Cacheable 
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 
public class FavoriteResourceFile extends IdEntity<FavoriteResourceFileId> { 

    @EmbeddedId 
    private FavoriteResourceFileId id; 

    @MapsId("resourceFileId") 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "resource_file_id", nullable = false) 
    private ResourceFile resourceFile; 

    ... 

} 

그리고 "다음 쿼리를 구성하는 모든 리소스 파일을 선택하고 좋아하는 리소스 파일의 수를 기준으로 정렬 할 ".

는 SQL에서 그것은 다음과 같습니다

select rf.id, count(frf.resource_file_id) from resource_file rf 
left join favorite_resource_file frf on frf.resource_file_id = rf.id 
group by rf.id 
order by count(rf.id) desc; 

하지만 마지막에 ResourceFile 엔티티 매핑을 만들기 위해 스프링 데이터 및 방법으로 작업을 수행하는 방법을 이해할 수 없습니다.

일부 제한 :

    그들은 다른 모듈에 위치하기 때문에 내가 ResourceFile에 FavoriteResourceFile에 를 관계를 만들 수 없습니다
  • 내가 네이티브 SQL 또는 JPA 쿼리를 사용하지 않으
  • (문자열로).
  • 메타 모델, 사양 또는 QueryDSL은 프로젝트에서 이미 사용되었으므로 메타 모델을 사용하는 것이 좋습니다.

나를 도와 줄 사람이 있습니까?

엔드 포인트 REPO :

public interface ResourceFileRepository extends 
    PagingAndSortingRepository<ResourceFile, Integer>, 
    ResourceFileRepositoryCustom { 
} 

사용자 정의의 repo :

public interface ResourceFileRepositoryCustom { 
    List<ResourceFile> getResourceFilesOrderByFavourites(); 
} 

사용자 정의

답변

6

이처럼는 Crud/PagingAndSorting 저장소 구현과 함께 사용자 정의 저장소 구현을 사용할 수 있습니다 repo 실제 코드를 구현하여 ResourceFile을 즐겨 찾기 개수로 정렬하십시오 (ResourceFileRepositoryImpl 및 R esourceFileRepositoryCustomImpl).

나는 임베디드 키가 없으므로 조금 간소화해야했습니다. ResourceFile이 FavoriteResourceFile과 관련이 없기 때문에 쿼리는 FavoriteResourceFile에서 시작합니다. https://github.com/rchukh/StackOverflowTests/tree/master/13669324

: 체크 아웃/포크/등 -
public class ResourceFileRepositoryImpl implements ResourceFileRepositoryCustom { 
    @PersistenceContext 
    private EntityManager em; 

    public void setEntityManager(EntityManager em) { 
     this.em = em; 
    } 

    @Override 
    public List<ResourceFile> getResourceFilesOrderByFavourites() { 
     CriteriaBuilder criteriaBuilder = this.em.getCriteriaBuilder(); 
     CriteriaQuery<ResourceFile> q = criteriaBuilder 
       .createQuery(ResourceFile.class); 
     Root<FavoriteResourceFile> root = q.from(FavoriteResourceFile.class); 
     Join<FavoriteResourceFile, ResourceFile> join = root.join(
       FavoriteResourceFile_.resourceFile, JoinType.LEFT); 
     q.select(join); 
     q.groupBy(join.get(ResourceFile_.id)); 
     q.orderBy(criteriaBuilder.desc(
         criteriaBuilder.count(
          join.get(ResourceFile_.id)))); 

     TypedQuery<ResourceFile> query = this.em.createQuery(q); 
     return query.getResultList(); 
    } 
} 

(일부 아주 기본적인 SQL 및 테스트 포함) 전체 예제 프로젝트를 참조하십시오