Java Reactor:如何将实体流转换为DTO对象流

Java Reactor:如何将实体流转换为DTO对象流,java,reactive-programming,dto,project-reactor,spring-data-r2dbc,Java,Reactive Programming,Dto,Project Reactor,Spring Data R2dbc,我有一个用户实体和一个角色实体。这些字段并不重要,只是用户实体有一个对应于其各自角色id的role_id字段。由于Spring数据R2DBC不处理实体之间的任何形式的关系,所以我转向DTO方法。作为一个整体,我对R2DBC和反应式编程非常陌生,我一辈子都不知道如何转换Flux我的存储库的findAll()方法将我返回到Flux。我的UserDto类非常简单: @Data @RequiredArgsConstructor public class UserDto { private fi

我有一个用户实体和一个角色实体。这些字段并不重要,只是用户实体有一个对应于其各自角色id的role_id字段。由于Spring数据R2DBC不处理实体之间的任何形式的关系,所以我转向DTO方法。作为一个整体,我对R2DBC和反应式编程非常陌生,我一辈子都不知道如何转换
Flux
我的存储库的findAll()方法将我返回到
Flux
。我的UserDto类非常简单:

@Data
@RequiredArgsConstructor
public class UserDto 
{
    private final User user;

    private final Role role;
}
下面是我尝试创建的UserMapper类:

@Service
@RequiredArgsConstructor
public class UserMapper 
{
    private final RoleRepository roleRepo;

    public Flux<UserDto> map(Flux<User> users)
    {
        //???
    }
}
@服务
@所需参数构造函数
公共类用户映射器
{
私人最终角色保留角色;
公共流量图(流量用户)
{
//???
}
}
如何让此映射器将
Flux
转换为包含用户各自角色的
Flux


谢谢

假设您的
RoleRepository
有一个
findById()
方法或类似方法来查找给定ID的
角色,并且您的用户对象有一个
getRoleId()
,您只需通过标准映射调用即可:

return users.map(u -> new UserDto(u, roleRepo.findById(u.getRoleId())));
或者如果
findById()
返回一个
Mono

return users.flatMap(u -> roleRepo.findById(u.getRoleId()).map(r -> new UserDto(u, r)));

当然,如果
getRoleId()
可能返回null,您可能需要添加额外的检查。

将数据从业务对象转换为数据库对象:

private static UserDAO covertUserBOToBUserDAO(UserBO userBO){
    return new UserDAO(userBO.getUserId(), userBO.getName(), userBO.getMobileNumber(), 
     userBO.getEmailId(), userBO.getPassword());
}
将数据从数据库对象转换为业务对象:

private static Mono<UserBO> covertUserDAOToBUserBO(UserDAO userDAO){
    return Mono.just(new UserBO(userDAO.getUserId(), userDAO.getName(), 
     userDAO.getMobileNumber(), userDAO.getEmailId(), userDAO.getPassword()));
}
private静态Mono-covertUserDAOToBUserBO(UserDAO-UserDAO){
返回Mono.just(新的UserBO(userDAO.getUserId(),userDAO.getName(),
userDAO.getMobileNumber()、userDAO.getEmailId()、userDAO.getPassword());
}
现在正在异步服务(getAllUsers):

public Flux<UserBO> getAllUsers(){
        return userRepository.findAll().flatMap(UserService::covertUserDAOToBUserBO);
}
公共流量getAllUsers(){
返回userRepository.findAll().flatMap(UserService::covertUserDaotoUserBo);
}
因为flatMap是异步的,所以我们可以从异步操作中获益,甚至可以将对象从DAO转换为BO。

同样,如果保存数据,我尝试了以下方法:

public Mono<UserBO> saveUser(UserBO userBO)
{
        return 
 userRepository.save(covertUserBOToBUserDAO(userBO)).flatMap(UserService::covertUserDAOToBUserBO);
}
public Mono-saveUser(UserBO-UserBO)
{
返回
userRepository.save(covertUserBOToBUserDAO(userBO)).flatMap(UserService::covertUserDAOToBUserBO);
}

谢谢Michael!我的头在旋转,我正在使用R2DBC和Webflux。我的目标是练习制作一个完全反应式的RESTAPI。您的解决方案是否有办法变得完全被动?另外,我使用的是被动存储库,因此RoleRepository的findById()方法返回Mono而不是Role,因此我无法以这种方式构造UserDto对象。@Martin只需调用另一个映射级别的
flatMap()
调用即可-请参阅我更新的答案。如果您使用的是R2DBC,那么请忽略我关于使用有界弹性调度器的评论。伙计,这种被动的东西很复杂!我希望建立这个项目将帮助我掌握的概念。感谢上帝,哈哈,干杯!我使用了JPA和Hibernate。我想这就是为什么很难掌握被动概念的原因。熟能生巧!