Я новичок в реактивном программировании. Мне нужно разработать простое приложение для весенней загрузки, чтобы вернуть ответ json, содержащий сведения о компании со всеми ее дочерними компаниями и сотрудниками.
Создал приложение для весенней загрузки (Spring Webflux + Spring data r2dbc)
Использование следующих таблиц базы данных для представления отношений между компанией и дочерней компанией и сотрудником (это иерархические отношения с компанией и дочерней компанией, в которой компания может иметь количество дочерних компаний N, и каждая из этих дочерних компаний может иметь еще N количество дочерних компаний. и т. д. и т. д.)
Компания
- id
- имя
- адрес
Company_SubCompany
- id
- sub_company_id (идентификатор ссылки на внешний ключ приведенной выше таблицы компании)
Работник
- id
- имя
- обозначение
- company_id (идентификатор ссылки на внешний ключ приведенной выше таблицы компании)
Ниже приведены классы модели Java для представления приведенных выше таблиц.
Company.java
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Company implements Serializable {
private int id;
private String name;
private String address;
@With
@Transient
private List<Company> subCompanies;
@With
@Transient
private List<Employee> employees;
}
Employee.java
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Employee implements Serializable {
@Id
private int id;
private String name;
private String designation;
}
Создаются следующие репозитории
@Repository
public interface CompanyRepository extends ReactiveCrudRepository<Company, Integer> {
@Query("select sub.sub_company_id from Company_SubCompany sub inner join Company c on sub.sub_company_id = c.id where sub.id = :id")
Flux<Integer> findSubCompnayIds(int id);
@Query("select * from Company c where id = :id")
Mono<Company> findCompanyById(Integer id);
}
@Repository
public interface EmployeeRepository extends ReactiveCrudRepository<Employee, Integer> {
@Query("select * from Employee where company_id = :id")
Flux<Employee> findEmployeeByCompanyId(Integer id);
}
В таблице Company_SubCompany суперкомпания представлена идентификатором -1. Таким образом, используя этот идентификатор, мы теперь можем получить родительскую компанию.
С приведенным ниже кодом обслуживания я теперь могу получить первый уровень компании и ее сотрудников. Но я не уверен, как получить все вложенные дочерние компании и добавить к ним
@Service
public class ComanyService {
@Autowired
CompanyRepository companyRepository;
@Autowired
EmployeeRepository employeeRepository;
public Flux<Company> findComapnyWithAllChilds() {
Flux<Integer> childCompanyIds = companyRepository.findSubCompnayIds(-1);
Flux<Company> companies = childCompanyIds.flatMap(p -> {
return Flux.zip(companyRepository.findCompanyById(p),
employeeRepository.findEmployeeByCompanyId(p).collectList(),
(t1, t2) -> t1.withEmployees(t2));
});
return companies;
}
}
Я новичок в реактивном функциональном программировании и r2dbc, поэтому, пожалуйста, помогите мне решить мою проблему. Если есть какой-либо другой лучший подход, мы также будем использовать его. Требование состоит в том, чтобы получить компанию, всех ее сотрудников и дочерние компании (до N уровня).
Converter<Row, YourClass>
, реализовав его в нашем интерфейсе репозитория, docs.spring.io/spring-data/r2dbc/docs/1.0.x/reference/html /, это интересно, попробую когда-нибудь. - person Ahmet OZKESEK   schedule 15.04.2020