简化,我有以下三个实体:
项目:
@Data
@Entity
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(unique = true)
private String name;
// more attributes
@NotNull
@ManyToOne
private Customer customer;
}
客户:
@Data
@Entity
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(unique = true)
private String name;
// more attributes
}
DailyEntry:
@Data
@Entity
public class DailyEntry {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
// more attributes
@ManyToOne
private Project project;
}
因此,该项目将客户作为属性,dailyEntry将项目作为属性。
我想获取与客户相关的所有DailyEntries。因此,我需要先获取与客户相关的所有项目,然后再获取与项目相关的所有DailyEntries。
我可以使用以下代码实现:
for (Customer customer : customerRepository.findAll()) {
for (Project project : projectRepository.findByCustomerId(customer.getId())) {
for (DailyEntry dailyEntry : dailyEntryRepository.findByProjectId(project.getId())) {
// can do sth with all the dailyEntries related to the customer here
}
}
}
}
但是用3个for循环来实现它似乎很糟糕/效率低下,因为它具有三次复杂性。真的像我想的那样糟糕吗?有没有一种更好的方法无需更改?
编辑:我尝试在findByCustomer
内实现一个DailyEntryRepository
查询。
@Query("SELECT dailyEntry FROM DailyEntry dailyEntry WHERE dailyEntry.project IN (SELECT pro FROM Project pro WHERE pro.customer.name = ?#{customer})")
List<DailyEntry> findByCustomer(Customer customer);
因此,在SQL编辑器中测试的查询有效,但是在将客户参数传递到存储库中时遇到了问题。客户不是日常进入的属性,因此它无法识别它。我使用上面的?#{customer}
注释进行了尝试,尝试使用@Param("customer") Customer customer
,但没有任何效果。如果该参数不是实体的属性,该如何将其传递给SQL查询?
答案 0 :(得分:0)
本质上,您正在查询数据库中所有的DailyEntry
实体(除非有些条目没有项目,而有些项目没有客户)。您应该使用dailyEntryRepository.findAll()
并通过单个SQL查询而不是两个嵌套循环来检索所有数据(这将导致多个SQL查询(除非您设置了缓存)。