0

目前,我正在尝试使用 Dataloader 模式 ( java-dataloader) 、JavaSpring BootSPQR来解决 N+1 问题Java Dataloader

我目前的实体设置如下:

@Setter
@Getter
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {

  private static final long serialVersionUID = 684733882540759135L;

  @Id
  @GeneratedValue
  @Column(columnDefinition = "uuid", updatable = false)
  @GraphQLQuery(name = "id", description = "A Person's Id")
  private UUID id;

  @NotNull(message = "There must be a Person's Name!")
  @GraphQLQuery(name = "fullName", description = "A Person's Name")
  private String fullName;

  @NotNull(message = "A Person must have an Age!")
  @GraphQLQuery(name = "age", description = "A Person's Age")
  private int age;

  @NotNull(message = "A Person must have a Vehicle!")
  @GraphQLQuery(name = "personalVehicle", description = "A Person's Mode of Transport")
  private Vehicle personalVehicle;

  @ManyToOne(targetEntity = Company.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  @GraphQLQuery(name = "company", description = "The Company a Person works for")
  private Company company;

  @GraphQLIgnore(reason = "None of your business!")
  private String socialSecurityNumber;

  public enum Vehicle {
    CAR,
    BUS,
    VAN,
    BICYCLE,
    MOTORBIKE,
    SCOOTER
  }

}

这是公司对象(在上面的类中引用)

@Setter
@Getter
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Company implements Serializable {

  private static final long serialVersionUID = -6007975840330441233L;

  @Id
  @GeneratedValue
  @Column(columnDefinition = "uuid", updatable = false)
  @GraphQLQuery(name = "id", description = "A Company's Id")
  private UUID id;

  @NotNull(message = "There must be a Company Name!")
  @GraphQLQuery(name = "name", description = "A Company's Name")
  private String name;

  @Min(10000)
  @NotNull(message = "You gotta tell us how rich you are!")
  @GraphQLQuery(name = "balance", description = "A Company's Dollar")
  private BigDecimal balance;

  @NotNull(message = "There must be a Company Type!")
  @GraphQLQuery(name = "type", description = "The type of company")
  private CompanyType type;

  public enum CompanyType {
    PRIVATE_LIMITED,
    SOLE_TRADER,
    PUBLIC
  }

}

我的 SPQR Resolvers/GraphQLApis 如图所示:

@Component
@GraphQLApi
@RequiredArgsConstructor
public class CompanyResolver {

  private final CompanyDao companyDao;

  @GraphQLQuery(name = "getAllCompanies")
  public List<Company> getAllCompanies() {
    return companyDao.findAll();
  }

  @GraphQLQuery(name = "getCompanyById")
  public CompletableFuture<Company> getCompanyById(@GraphQLArgument(name = "id") @GraphQLNonNull @Valid UUID id, @GraphQLEnvironment ResolutionEnvironment env) {
    DataLoader<UUID, Company> loader = env.dataFetchingEnvironment.getDataLoader("company");
    return loader.load(id);
  }

  @GraphQLMutation(name = "saveCompany")
  public Company saveCompany(@GraphQLArgument(name = "company") @GraphQLNonNull @Valid Company company) {
    return companyDao.save(company);
  }

  @GraphQLMutation(name = "deleteCompany")
  public void deleteCompany(@GraphQLArgument(name = "id") @GraphQLNonNull @Valid UUID companyId) {
    companyDao.deleteById(companyId);
  }
}

@GraphQLApi
@Component
@RequiredArgsConstructor
public class EmployeeResolver {

  private final EmployeeDao employeeDao;

  @GraphQLQuery(name = "getAllEmployees")
  public List<Employee> getAllEmployees() {
    return employeeDao.findAll();
  }

  @GraphQLQuery(name = "getEmployeeById")
  public Optional<Employee> getEmployeeById(@GraphQLArgument(name = "id") @GraphQLNonNull @Valid UUID id) {
    return employeeDao.findById(id);
  }

  @GraphQLMutation(name = "saveEmployee")
  public Employee saveEmployee(@GraphQLArgument(name = "employee") @GraphQLNonNull @Valid Employee company) {
    return employeeDao.save(company);
  }

  @GraphQLMutation(name = "deleteEmployee")
  public void deleteEmployee(@GraphQLArgument(name = "id") @GraphQLNonNull @Valid UUID companyId) {
    employeeDao.deleteById(companyId);
  }
}

我的数据加载器都设置正确,但我需要Employee实体的company字段来使用数据加载器,如getCompanyById查询中所示 - 以避免相关对象的 N+1 问题。

如果我完全错了,请说 - 我是 SPQR 的菜鸟。任何答案或澄清问题将不胜感激!谢谢!

4

0 回答 0