简体   繁体   English

Spring数据R2DBC如何查询分层数据

[英]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我必须开发一个简单的 spring 启动应用程序以返回 json 响应,其中包含公司及其所有子公司和员工的详细信息

Created a spring boot application (Spring Webflux + Spring data r2dbc )创建了一个 spring 引导应用程序(Spring Webflux + Spring 数据 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)使用以下数据库表来表示公司与子公司和员工的关系(它是与公司和子公司的层级关系,其中一个公司可以有 N 个子公司,每个子公司可以有另外 N 个子公司等等等等)

Company公司

  • id ID
  • name姓名
  • address地址

Company_SubCompany公司_子公司

  • id ID
  • sub_company_id (foreign key references id of above company table ) sub_company_id(上面公司表的外键引用id)

Employee员工

  • id ID
  • name姓名
  • designation指定
  • company_id ( foreign key references id of above company table ) company_id(上述公司表的外键引用id)

Following are the java model classes to represent the above tables以下是代表上述表格的 java model 类

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

Employee.java员工.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.在 Company_SubCompany 表中,超级公司用 id -1 表示。 So using this id we are now able to get the super parent company.所以使用这个id我们现在可以得到超级母公司。

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.我对反应式、函数式编程和 r2dbc 非常陌生,所以请帮助我解决我的问题。 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).要求是获得公司、其所有员工和子公司(最多 N 个休假)。

this code can help you, this approach fill the List objects from database calls此代码可以帮助您,这种方法从数据库调用中填充 List 对象

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

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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