希望使我的数据库搜索更高效

时间:2019-11-11 14:34:47

标签: java jpa

简化,我有以下三个实体:

项目:

@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查询?

1 个答案:

答案 0 :(得分:0)

本质上,您正在查询数据库中所有的DailyEntry实体(除非有些条目没有项目,而有些项目没有客户)。您应该使用dailyEntryRepository.findAll()并通过单个SQL查询而不是两个嵌套循环来检索所有数据(这将导致多个SQL查询(除非您设置了缓存)。