spring-boot - Spring Data JPA DistinctBy 预测
问题描述
冬眠者们美好的一天!我有一个关于DistinctBy子句如何与Spring Data 的投影结合使用的问题
假设我有 3 个课程:
public class Task {
Long id;
@ManyToOne(fetch = LAZY)
@JoinColumn(name = "project_id")
private Project project;
@OneToOne
@JoinColumn(name = "contact_id")
private Contact assigned;
Boolean deleted;
// ...
}
public class Contact {
Long id;
// ...
}
public class Project {
Long id;
@OneToMany(fetch = LAZY, mappedBy = "project")
private Set<Task> tasks;
// ...
}
这些将是我的域类。请注意,Project 确实对 Tasks 有“One2Many”,而 Contact 没有。现在,我有 2 个用于我的预测的接口和具有 2 种方法的基本 TaskRepo:
public interface JustProject {
Project getProject();
}
public interface JustAssignee {
Contact getContact();
}
public class TaskRepo extends CrudRepository<Task, Long>, JpaSpecificationExecutor<Task> {
List<JustAssignee> findDistinctByDeletedFalse();
List<JustProject> findDistinctByDeletedFalseAndDeletedFalse();
}
它现在对我有用的方式是,findDistinctByDeletedFalse
返回与任务的不同联系人一样多的实例(例如,如果有 10 个任务但只有 3 个联系人,该方法将只返回包含所有 3 个不同联系人的 3 个对象)。相同,findDistinctByDeletedFalseAndDeletedFalse
但在项目级别。
现在我在这里有几个问题,很想得到一些帮助来理解它是如何工作的。
搜索完成后是否应用了distinct子句?
- 我最初的假设是这种行为不会像现在这样起作用。我假设在获取结果之前应用了 distinct 子句,这意味着它将是基于底层任务模型的 DISTINCT,而不是返回的
JustContact
或JustProject
模型。
- 我最初的假设是这种行为不会像现在这样起作用。我假设在获取结果之前应用了 distinct 子句,这意味着它将是基于底层任务模型的 DISTINCT,而不是返回的
有什么办法可以不滥用
...AndDeletedFalse
多余的附录?我需要回购中的两种方法,但我觉得我必须作弊才能获得结果......... 难道我做错了什么?我想尽可能优雅地获得“分配给所有任务的所有不同联系人/项目”。我最终想到了这个 distinctby 正是因为我不确定它是如何工作的,并且想试试运气。我真的不认为它会以这种方式工作,但现在它确实如此,我真的很想了解它为什么会这样!
非常感谢<3
解决方案
关键字应用于查询,因此
DISTINCT
它的效果取决于选择列表,而选择列表又由投影控制。因此,如果您只有project
或仅contact
在您的投影中,DISTINCT
则将仅应用于这些值。但请注意,这在一定程度上依赖于 JPA 规范的边界,如果您看到不同实现的不同行为,我不会感到惊讶。有关针对规范提出的一些相关问题,请参阅https://github.com/eclipse-ee4j/jpa-api/issues/189和https://github.com/eclipse-ee4j/jpa-api/issues/124 。find
为了区分仅返回值不同的方法,您可以在方法名称之间和方法名称中添加任何其他字符串By
。例如,您可能希望将您的方法重命名findDistinctContactsByDeletedFalse
为findDistinctProjectsByDeletedFalse
推荐阅读
- ios - 科尔多瓦 IOS 应用程序所有 onclick 和后退按钮不适用于最新的 IOS 11.3.1
- php - 对象中的 mysqli_fetch_assoc
- html - 科尔多瓦文件下载并使用科尔多瓦打开它
- java - 将 Curl -G 转换为 java 代码
- sql - 使用 UTL_FILE 包远程读写文本文件
- python - Python 究竟是如何检查列表的?
- python - 如何更新软件包哈希?
- javascript - Javascript 和 jQuery 都停止在 for 循环中删除选项
- php - 在 Bootstrap 日期选择器中禁用过去的日期
- elasticsearch - 需要通过 URI 示例进行 Elasticsearch 多索引搜索