5

私には2つのエンティティがあります:

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;

しかし、Spring Dataを使用してそれを行う方法と、最後にResourceFileエンティティにマッピングする方法を理解できません。

いくつかの制限:

  • 別のモジュールにあるため、ResourceFileのFavoriteResourceFileとの関係を作成できません
  • ネイティブSQLまたはJPAクエリを(文字列として)使用したくありません。
  • メタモデル、仕様、またはQueryDSLはすでにプロジェクトで使用されているため、これらを使用することをお勧めします。

誰かが私を助けることができますか?

4

1 に答える 1

6

次のように、カスタムリポジトリの実装をCrud/PagingAndSortingリポジトリの実装と一緒に使用できます。

エンドポイントリポジトリ:

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

カスタムリポジトリ:

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

お気に入りの数で並べ替えられたResourceFileを取得するための実際のコードを使用したカスタムリポジトリの実装(ResourceFileRepositoryCustomImplではなくResourceFileRepositoryImplであることに注意してください)。

私はそれらの埋め込まれたキーを持っていなかったので、それを少し単純化する必要がありました。ResourceFileはFavoriteResourceFileと独自の関係を持っていないため、クエリはFavoriteResourceFileから送信されます。

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とテストを含む)を表示するには-checkout / fork / etc: https ://github.com/rchukh/StackOverflowTests/tree/master/13669324

于 2012-12-08T11:46:03.000 に答える