java - Spring Data R2DBC 如何查询分层数据

标签 java asynchronous project-reactor spring-data-r2dbc r2dbc

我是响应式(Reactive)编程的新手。我必须开发一个简单的 spring boot 应用程序来返回一个 json 响应,其中包含公司所有子公司和员工的详细信息
创建了一个spring boot应用程序(Spring Webflux + Spring data r2dbc)
使用以下数据库表来表示公司和子公司以及员工关系(公司和子公司之间的层级关系,一个公司可以有N个子公司,每个子公司又可以有N个子公司等等等等)
公司

  • id
  • 姓名
  • 地址

  • 公司_子公司
  • id
  • sub_company_id(上面公司表的外键引用id)

  • 员工
  • id
  • 姓名
  • 名称
  • company_id(上述公司表的外键引用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 表中, super 公司用 id -1 表示。因此,使用此 ID,我们现在可以获取 super 母公司。
    使用以下服务代码,我现在可以获得公司及其员工的第一级。但我不确定如何获取所有嵌套的子公司并添加到其中
    @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;
        }
    }
    
    我对响应式(Reactive)、函数式编程和 r2dbc 很陌生,所以请帮助我解决我的问题。如果有任何其他更好的方法可用,也将使用该方法。要求是获取公司、其所有员工和子公司(最多 N leavel)。

    最佳答案

    这段代码可以帮助你,这种方法从数据库调用中填充 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()))
                );
    
    }

    关于java - Spring Data R2DBC 如何查询分层数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61211628/

    相关文章:

    spring-boot - 配置 Spring WebFlux WebClient 以使用自定义线程池

    java - 斯巴达克斯中的 SmartEdit 设置

    java - 读取并存储txt。数组列表中的文件内容

    c# - 在 C# 中使代码异步

    scala - 您会在 scala Play Framework 2 中从外部缓存 (Redis) 异步检索结果吗?

    java - 将一个单声道对象转换为两个不同的单声道对象,并且根单声道对象执行两次

    java - 如何让服务层在从数据库中获取任何内容时返回 Mono::error

    java - Apache Cayenne - 我找不到定义 Token.kind 字段常量的代码

    java - 如何在 Java 的数据源中实现 getConnection()?

    python - 我如何*正确*在循环中运行 asyncio/aiohttp 请求?