gpt4 book ai didi

java - 如何在 Spring Data 中制作 "order by aggregate function"?

转载 作者:搜寻专家 更新时间:2023-10-31 19:56:37 25 4
gpt4 key购买 nike

我有两个实体:

资源文件:

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

...
}

最喜欢的资源文件:

@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 建立关系,因为它们位于不同的模块
  • 我不想使用 native SQL 或 JPA 查询(作为字符串)。
  • 最好使用元模型、规范或 QueryDSL,因为它们已经在项目中使用。

有人可以帮助我吗?

最佳答案

您可以将自定义存储库实现与 Crud/PagingAndSorting 存储库实现一起使用,如下所示:

端点 repo :

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

自定义 repo :

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

使用实际代码的自定义 repo 实现以按 Collection 计数检索 ResourceFile 的顺序(注意它是 ResourceFileRepositoryImpl 而不是 ResourceFileRepositoryCustomImpl)。

我没有那些嵌入的键,所以我不得不稍微简化一下。查询从 FavoriteResourceFile 开始,因为 ResourceFile 与 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

关于java - 如何在 Spring Data 中制作 "order by aggregate function"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13669324/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com