我有一些
DepartmentView
与另一个视图UserDepartmentView
有@OneToMany关系,我的问题是当我尝试加载所有部门时需要太多时间。
在本地加载 600 个条目需要大约 4 秒,在生产环境中需要更多时间
我尝试使用@EntityGraph 实现,但它并没有真正帮助我减少加载时间。
知道如何优化代码以缩短加载时间吗?附注
DepartmentView
还有更多其他属性,我只是没有在代码片段中列出
public List<DepartmentDTO> getDepartments() {
Specification<DepartmentView> specification = getSomeSpecification();
List<DepartmentView> departmentViews = departmentViewRepo.findAll(specification);
return departmentViews
.stream()
.map(DepartmentDTO::new)
.toList();
}
public interface DepartmentViewRepository extends CrudRepository<DepartmentView, String>, JpaSpecificationExecutor<DepartmentView> {
@EntityGraph(attributePaths = {"users"}, type = EntityGraph.EntityGraphType.LOAD)
List<DepartmentView> findAll(Specification<DepartmentView> specification);
}
@Entity
@Immutable
@Table(name = "department_view")
public class DepartmentView implements Serializable {
@Id
@Column(name = "id", nullable = false)
private String id;
@Column(name = "name")
private String name;
@Column(name = "department_id")
private String departmentId;
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
@JsonBackReference
@ToString.Exclude
private List<UserDepartmentView> users;
}
@Entity
@Immutable
@Table(name = "user_department_view")
public class UserDepartmentView {
@Id
@Column(name = "id", nullable = false)
private String id;
@Column(name = "name")
private String name;
@Column(name = "last_name")
private String lastName;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_department_id", referencedColumnName = "department_id")
@JsonIgnore
@ToString.Exclude
private DepartmentView department;
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class DepartmentDTO {
private String id;
private String departmentId;
private String name;
private List<UserDTO> users;
public DepartmentDTO(DepartmentView departmentView) {
this.setId(departmentView.getId());
this.setDepartmentId(departmentView.getRequirementId());
this.setName(departmentView.getName());
this.setDataUsers(getUsers(departmentView));
}
private static List<UserDTO> getUsers(DepartmentView departmentView) {
return departmentView.getUsers()
.stream()
.map(UserDTO::new)
.collect(Collectors.toList());
}
}
在您的示例中,如果您有部门实体和用户实体。一个部门可以有多个用户,因此部门实体中存在一对多的关系。用户只能属于一个部门,因此用户实体中存在多对一关系。因此,如果您想获取一个部门的所有用户,只需通过用户实体即可。最好只选择 *from User where Department = ?然后通过部门表选择它们,一对多正在执行此操作。
另一种方法是创建用户和部门之间的关系表,例如 user_department。然后你将有一个名为 f.e 的实体。 UserDepartmentRelation 其中您将有两个多对一关系(一个与用户,一个与部门)。因此,您可以使用此关系实体来获取一个部门的用户,并以某种方式将数据从关系实体映射到您的 dto 对象。该关系表和实体通常用于多对多关系,但也可以用于这种情况。
我可以看到的另一件事是,您似乎正在使用数据库中的视图。视图通常比仅通过连接进行选择要慢。您还可以使用列索引机制,这也可以帮助您消除性能问题。