【发布时间】:2022-09-30 19:51:03
【问题描述】:
我正在使用 Spring Boot JPA 来获取对象列表(现在使用 Java 8)。每个对象都有关系,我也使用相关对象转换为 dto 列表。 假设我有以下模型类。
public class Product {
@EmbeddedId
private ProductId id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = \"userid\", referencedColumnName = \"USER_ID\")
@MapsId(\"userId\")
private User owner;
}
public class User {
@Id
@Column(name = \"USER_ID\")
private Long userId;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = \"gp_code\", referencedColumnName = \"GP_CODE\")
@JoinColumn(name = \"userid\", referencedColumnName = \"USER_ID\")
private UserGroup userGroup;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumnsOrFormulas(value = {
@JoinColumnOrFormula(formula = @JoinFormula(value = \"country_id\", referencedColumnName = \"COUNTRY_ID\")),
@JoinColumnOrFormula(column = @JoinColumn(name = \"region_code\", referencedColumnName = \"REGION_CODE\")) })
private Country country;
}
我查询List<Product> 并使用流将其转换为 dto 对象。在此期间,我调用相关实体来获取数据。我有下面的代码并且工作正常,除非列表太多。如果列表中有 1000 多个项目,则大约需要 30 秒。
我相信由于延迟加载,这种情况正在发生。优化它的最佳方法是什么? 一种选择是进行分页,但我不能这样做。我需要所有结果。
有没有办法并行执行这个?我尝试调用并行 Stream() 而不是 stream(),但结果相同。
public List<ProductDTO> getProducts(String countryId) {
//List<Product> products = Query Result
List<ProductDTO> productsList = products.stream().filter(isOwnerFromCountryAndInAnyGroup(countryId))
.map(product -> getProductDTO(product)).collect(Collectors.toList());
}
private Predicate<? super Product> isOwnerFromCountryAndInAnyGroup(String countryId) {
return product -> {
User user = product.getOwner();
return null != user && null != user.getCountry()
&& user.getCountry().getCountryId().equals(countryId) && (null != user.getUserGroup());
};
}
private ProductDTO getProductDTO(Product product) {
ProductDTO productDTO = new ProductDTO();
productDTO.setProductNbr(product.getId().getProductNbr());
productDTO.setPrice(product.getPrice());
productDTO.setOwnerName(product.getOwner().getName());
return productDTO;
}
编辑
为了在这里提问,我错过了添加productDTO.setOwnerName(product.getOwner().getName()); 行。通过查询或使用过滤器,我得到了正确数量的结果。并且通过延迟加载,查询返回更快,然后在为每一行调用 getOwner() 时,该过程需要时间(30 秒)。
使用 FethType.EAGER,查询需要相似的时间(30 秒),然后处理速度更快。无论哪种方式,它都是相似的时间。
为了加快流程,有没有办法并行执行流代码块并将所有结果收集到列表中?
-
与我们分享查询,我相信应该有问题
-
只是一个建议 - 通常我们使用 fetch type lazy - 当我们有 ManyToOne 映射时 - 以节省检索时间并仅在需要时加载。对于 OneToOne 和 ManyToOne - 使用 fetch 类型急切不会是一项昂贵的操作
-
@PanagiotisBougioukos 它是通过查询找到的。查询响应更快。
-
@AshishShetkar 谢谢。我想我可以做出改变并尝试
-
你能分享一下什么类型的findBy吗?
标签: java java-stream