Reactor:如何将实体的Flux转换为DTO对象的Flux

9

我有一个用户实体和一个角色实体。除了用户实体具有对应于其相关角色的ID的role_id字段之外,其他字段并不重要。由于Spring Data R2DBC不会在实体之间执行任何形式的关系,因此我转向DTO方法。 我非常新于R2DBC和响应式编程,但却无法想出如何将我的存储库的findAll()方法返回的Flux<User>转换为Flux<UserDto>。我的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<User> 转换为一个包含用户对应角色的 Flux<UserDto>

谢谢!

2个回答

8
假设您的 RoleRepository 具有类似于查找给定 ID 的 RolefindById() 方法,且您的用户对象具有获取角色 ID 的 getRoleId() 方法,则只需通过标准的 map 调用即可完成:
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,你当然可以添加额外的检查。


谢谢你,迈克尔!我的头有些晕了,我正在使用R2DBC和Webflux。我的目标是练习制作一个完全反应式的REST API。你的解决方案有没有办法变成完全反应式的呢? - Martin
而且,我正在使用响应式存储库,因此RoleRepository的findById()方法返回的是Mono<Role>而不是Role,因此我无法以这种方式构造UserDto对象。 - Martin
1
这个响应式的东西有点复杂啊!我希望通过构建这个项目来理解其中的概念。谢天谢地StackOverflow存在,哈哈。干杯! - Martin
@Martin 这是一种不同的思考方式,但当你掌握了几个不同的例子和用例后,你会发现它变得非常自然。它还有助于强制实现不可变性/减少副作用;就我个人而言,我发现这比使用标准POJOs编码更具有弹性。 - Michael Berry
1
我曾经用过JPA和Hibernate,反复琢磨了很久。我认为这就是为什么理解响应式概念如此困难的原因。熟能生巧! - Martin
显示剩余3条评论

0

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

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

现在异步提供服务 (getAllUsers):

public Flux<UserBO> getAllUsers(){
        return userRepository.findAll().flatMap(UserService::covertUserDAOToBUserBO);
}

由于flatMap是异步的,因此我们可以从异步操作中获得好处,即使将对象从DAO转换为BO。

同样,如果保存数据,则我尝试如下:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接