Spring Data R2DB C как запрашивать иерархические данные - PullRequest
0 голосов
/ 14 апреля 2020

Я новичок в Реактивном программировании. Мне нужно разработать простое приложение весенней загрузки, чтобы получить ответ json, который содержит сведения о компании со всеми ее дочерними компаниями и сотрудниками

Создано приложение весенней загрузки (Spring Webflux + Spring data r2db c)

Использование следующих таблиц базы данных для представления отношений между компанией и дочерней компанией и сотрудником (это иерархические отношения с компанией и дочерней компанией, в которых у компании может быть N количество дочерних компаний, и каждая из этих дочерних компаний может иметь еще N количество дочерних компаний и т. д. c и т. д.)

Компания

  • id
  • имя
  • адрес

Company_SubCompany

  • id
  • sub_company_id (идентификатор внешнего ключа для вышеуказанной таблицы компании)

Сотрудник

  • id
  • name
  • Обозначение
  • company_id (идентификатор внешнего ключа в приведенной выше таблице компании)

Ниже приводится модель java классы для представления таблиц выше

Компания. 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;
}

Сотрудник. 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;
    }
}

Я очень плохо знаком с реактивным, функциональным программированием и r2db c, поэтому, пожалуйста, помогите мне, как решить мои проблема. Если есть какой-либо другой лучший доступный подход, будет использовать и этот. Требование состоит в том, чтобы получить компанию, всех ее сотрудников и дочерние компании (до уровня N).

...