简体   繁体   中英

Spring Data R2DBC how to query hierarchical data

I am new to Reactive programming. I have to develop a simple spring boot application to return a json response which contains the company details with all its sub companies and employees

Created a spring boot application (Spring Webflux + Spring data r2dbc )

Using following Database Tables to represent the Company and Sub Company and Employee relationship (it is a hierarchical relationship with Company and Sub Company where a company can have N number of sub companies, and each of these sub companies can have another N number of sub companies etc and so on)

Company

  • id
  • name
  • address

Company_SubCompany

  • id
  • sub_company_id (foreign key references id of above company table )

Employee

  • id
  • name
  • designation
  • company_id ( foreign key references id of above company table )

Following are the java model classes to represent the above tables

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;  
    
}

Following repositories are created

@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);

}

In Company_SubCompany table, the super company is represented with id -1. So using this id we are now able to get the super parent company.

With the below service code i am now able to get first level of company and its employees. But i am not sure how to get all the nested sub companies and add to it

@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;
    }
}

I am very new to reactive, functional programing and r2dbc, so please help me to how to resolve my problem. If there is any other better approach available will use that one also. The requirement is to get the company, all its employees and sub companies (upto N leavel).

this code can help you, this approach fill the List objects from database calls

public Flux<Company> findComapnyWithAllChilds(){
    return companyRepository.findAll()
            .flatMap(companies ->
                    Mono.just(companies)
                    .zipWith(employeeRepository.findEmployeeByCompanyId(companies.getId()).collectList())
                    .map(tupla -> tupla.getT1().withEmployees(tupla.getT2()))
                        .zipWith(anotherRepository.findAnotherByCompanyId(companies.getId()).collectList())
                        .map(tupla -> tupla.getT1().withAnother(tupla.getT2()))
            );

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM