如何将 MapStruct 用于不同的数据类型?
How to use MapStruct for different data types?
我有两种类型的数据要映射:
SignUpUserDto:
public class SignUpUserDto {
private String firstName;
private String lastName;
private String username;
private String email;
private String password;
private String title;
}
注册用户:
@Entity
public class SignUpUser {
private Long id;
private String firstName;
private String lastName;
private String username;
private String email;
private String password;
private Title title;
}
标题:
public enum Title {
JUNIOR("junior"),
MIDDLE("middle"),
SENIOR("senior"),
MANAGER("manager");
private final String title;
Title(final String title) {
this.title = title;
}
public String toString() {
return this.title;
}
}
对于DTO title 成员是一个String.
For entity title 成员是 Title.
映射器应该是什么样子的?
我是否应该传递已在 Service 中转换的标题?
@Mapper(componentModel = "spring")
public interface SignUpUserMapper {
SignUpUserMapper INSTANCE = Mappers.getMapper(SignUpUserMapper.class);
@Mapping(target = "title", expression = "title")
public SignUpUserDto signUpUserToSignUpUserDto(SignUpUser signUpUser, String title);
@Mapping(target = "title", source = "title")
public SignUpUser signUpUserDtoToSignUpUser(SignUpUserDto signUpUserDto, Title title);
}
还是应该在 Mapper 中进行转换?
@Mapper(componentModel = "spring", imports = Title.class)
public interface SignUpUserMapper {
SignUpUserMapper INSTANCE = Mappers.getMapper(SignUpUserMapper.class);
@Mapping(target = "title", expression = "java(signUpUser.getTitle().toString())")
public SignUpUserDto signUpUserToSignUpUserDto(SignUpUser signUpUser);
@Mapping(target = "title", source = "java(new Title(signUpUserDto.getTitle()))")
public SignUpUser signUpUserDtoToSignUpUser(SignUpUserDto signUpUserDto);
}
像这样使用第二个选项:
@Mapper(componentModel = "spring", imports = Title.class)
public interface SignUpUserMapper {
SignUpUserMapper INSTANCE = Mappers.getMapper(SignUpUserMapper.class);
@Mapping(target = "title", expression = "java(signUpUser.getTitle().toString())")
public SignUpUserDto signUpUserToSignUpUserDto(SignUpUser signUpUser);
@Mapping(target = "title", source = "java(Title.valueOf(signUpUserDto.getTitle().toUpperCase()))")
public SignUpUser signUpUserDtoToSignUpUser(SignUpUserDto signUpUserDto);
}
Should I pass title already converted in Service?
你绝对不应该这样做。这是转换器的工作,不是服务的工作
尝试以下方法:
1) 添加转换方法到枚举class
enum Title {
...
public static Title fromString(String title) {
if (title != null) {
for (Title t : Title.values()) {
if (t.toString().equals(title)) {
return t;
}
}
}
return null;
}
}
2) Mapper接口增加2个转换方法(Java 8+ only)
@Mapper(componentModel = "spring")
public interface SignUpUserMapper {
SignUpUserDto signUpUserToSignUpUserDto(SignUpUser signUpUser);
SignUpUser signUpUserDtoToSignUpUser(SignUpUserDto signUpUserDto);
default String fromEnum(Title title) {
return title == null ? null : title.toString();
}
default Title toEnum(String title) {
return title == null ? null : Title.fromString(title);
}
}
我有两种类型的数据要映射:
SignUpUserDto:
public class SignUpUserDto {
private String firstName;
private String lastName;
private String username;
private String email;
private String password;
private String title;
}
注册用户:
@Entity
public class SignUpUser {
private Long id;
private String firstName;
private String lastName;
private String username;
private String email;
private String password;
private Title title;
}
标题:
public enum Title {
JUNIOR("junior"),
MIDDLE("middle"),
SENIOR("senior"),
MANAGER("manager");
private final String title;
Title(final String title) {
this.title = title;
}
public String toString() {
return this.title;
}
}
对于DTO title 成员是一个String.
For entity title 成员是 Title.
映射器应该是什么样子的?
我是否应该传递已在 Service 中转换的标题?
@Mapper(componentModel = "spring")
public interface SignUpUserMapper {
SignUpUserMapper INSTANCE = Mappers.getMapper(SignUpUserMapper.class);
@Mapping(target = "title", expression = "title")
public SignUpUserDto signUpUserToSignUpUserDto(SignUpUser signUpUser, String title);
@Mapping(target = "title", source = "title")
public SignUpUser signUpUserDtoToSignUpUser(SignUpUserDto signUpUserDto, Title title);
}
还是应该在 Mapper 中进行转换?
@Mapper(componentModel = "spring", imports = Title.class)
public interface SignUpUserMapper {
SignUpUserMapper INSTANCE = Mappers.getMapper(SignUpUserMapper.class);
@Mapping(target = "title", expression = "java(signUpUser.getTitle().toString())")
public SignUpUserDto signUpUserToSignUpUserDto(SignUpUser signUpUser);
@Mapping(target = "title", source = "java(new Title(signUpUserDto.getTitle()))")
public SignUpUser signUpUserDtoToSignUpUser(SignUpUserDto signUpUserDto);
}
像这样使用第二个选项:
@Mapper(componentModel = "spring", imports = Title.class)
public interface SignUpUserMapper {
SignUpUserMapper INSTANCE = Mappers.getMapper(SignUpUserMapper.class);
@Mapping(target = "title", expression = "java(signUpUser.getTitle().toString())")
public SignUpUserDto signUpUserToSignUpUserDto(SignUpUser signUpUser);
@Mapping(target = "title", source = "java(Title.valueOf(signUpUserDto.getTitle().toUpperCase()))")
public SignUpUser signUpUserDtoToSignUpUser(SignUpUserDto signUpUserDto);
}
Should I pass title already converted in Service?
你绝对不应该这样做。这是转换器的工作,不是服务的工作
尝试以下方法:
1) 添加转换方法到枚举class
enum Title {
...
public static Title fromString(String title) {
if (title != null) {
for (Title t : Title.values()) {
if (t.toString().equals(title)) {
return t;
}
}
}
return null;
}
}
2) Mapper接口增加2个转换方法(Java 8+ only)
@Mapper(componentModel = "spring")
public interface SignUpUserMapper {
SignUpUserDto signUpUserToSignUpUserDto(SignUpUser signUpUser);
SignUpUser signUpUserDtoToSignUpUser(SignUpUserDto signUpUserDto);
default String fromEnum(Title title) {
return title == null ? null : title.toString();
}
default Title toEnum(String title) {
return title == null ? null : Title.fromString(title);
}
}