2012-12-02 6 views
5

Ich habe zwei Entitäten:Wie man in Spring Data "nach Aggregatfunktion sortieren"?

Resource:

@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; 

    ... 

} 

Und ich möchte alle Ressourcendateien die folgende Abfrage „auswählen und gräflichen von Lieblingsressourcendatei sortieren machen ".

In SQL es aussieht:

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; 

Aber ich kann nicht verstehen, wie es mit Spring Data zu tun und wie Abbildung auf Resource Einheit am Ende zu machen.

einige Einschränkungen:

  • ich nicht Bezug auf FavoriteResourceFile in Resource machen können, , weil sie in verschiedenen Modulen
  • befinden Ich möchte nicht nativen SQL oder JPA-Abfrage verwenden (als Strings).
  • Es ist vorzuziehen, Meta-Modelle, Specification oder QueryDSL zu verwenden, da sie bereits im Projekt verwendet werden.

Kann mir jemand helfen?

Antwort

6

Sie können Ihre benutzerdefinierten Repository Implementierung zusammen mit Crud/PagingAndSorting Repository Implementierung wie folgt verwenden:

End-Punkt-Repo:

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

Individuelle Repo:

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

Gewohnheit Repo-Implementierung mit aktuellem Code, um ResourceFile nach der Anzahl der Favoriten abzurufen (beachten Sie, dass es ResourceFileRepositoryImpl ist und nicht R esourceFileRepositoryCustomImpl).

Ich hatte diese eingebetteten Schlüssel nicht, also musste ich es ein wenig vereinfachen. Die Abfrage wird von der FavoriteResourceFile ausgeführt, da ResourceFile keine eigene Beziehung zu FavoriteResourceFile hat. https://github.com/rchukh/StackOverflowTests/tree/master/13669324

: Kasse/Gabel/etc -

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

Um ein volles Beispielprojekt (mit einigen sehr einfachen SQL-und-Test) zu sehen

Verwandte Themen