使用 MapStruct 将成员变量转换为 id(反之亦然)

Use MapStruct to convert member variable to id (and vice versa)

在我的 SpringBoot 应用程序中,我有两个实体 UserRole 以及

public class User {
    private Long id;
    private String email;
    private String password;
    private Set<Role> roles;

    [...]
}

public class Role {
    private Long id;
    private String name;
    private Set<User> users;

    [...]
}

我的 DTO 看起来非常相似,直到我意识到这可能会导致递归问题,当 user 有一个字段 role,它有一个相同的字段 user,有相同的字段role,等等

因此我决定只将 id 交给我的 DTO,所以它们看起来像这样

public class UserDto {

    private Long id;
    private String email;
    private String password;
    private List<Long> roleIds;
}

public class RoleDto {
    private Long id;
    private String name;
    private List<Long> userIds;
}

我的映射器非常简单,以前看起来像这样

import org.mapstruct.Mapper;
@Mapper
public interface UserMapper {
    User userDtoToUser(UserDto userDto);
    UserDto userToUserDto(User user);
    List<UserDto> userListToUserDtoList(List<User> users);
}


import org.mapstruct.Mapper;
@Mapper
public interface RoleMapper {
    Role roleDtoToRole(RoleDto roleDto);
    RoleDto roleToRoleDto(Role Role);
    List<RoleDto> roleListToRoleDtoList(List<Role> roles);
}

我要如何更改它们才能将 users to/from userIdsroles to/from roleIds?

rolesrolesDtosusersusersDtos的单向映射非常简单

@Mapper
public interface RoleMapper {

    List<RoleDto> roleListToRoleDtoList(List<Role> role);

    @Mapping(target = "userIds", source = "users", qualifiedByName = "userListToUserDtoList")
    RoleDto roleToRoleDto(Role role);

    @Named("userListToUserDtoList")
    default List<Long> userListToUserDtoList(Set<User> users) {
        return users.stream().map(User::getId).collect(Collectors.toList());
    }
}

@Mapper
public interface UserMapper {

    List<UserDto> userListToUserDtoList(List<User> users);

    @Mapping(target = "roleIds", source = "roles", qualifiedByName = "roleListToRoleDtoList")
    UserDto userToUserDto(User user);

    @Named("roleListToRoleDtoList")
    default List<Long> roleListToRoleDtoList(Set<Role> roles) {
        return roles.stream().map(Role::getId).collect(Collectors.toList());
    }
}

真正的问题是映射

User userDtoToUser(UserDto userDto);

Role roleDtoToRole(RoleDto roleDto);

因为这里 MapStruct 不知道如何将 userIds 转换为 users 你需要一些机制来获取每个 userId 并将其解析为整个对象。如果您正在使用 Spring,您可以将映射器作为 Spring beans - https://mapstruct.org/documentation/stable/reference/html/#using-dependency-injection or decorators https://mapstruct.org/documentation/stable/reference/html/#decorators-with-spring 用于“获取方法”以某种方式注入适当的存储库。
,但在这里我会考虑是否值得为你的定向映射中的 recursion 案例挖掘或实施一些专用方法。