如何在 MapStruct 中映射扩展 类
How to map extended classes in MapStruct
关于 mapStruct 的问题。我遇到过从基本实体扩展 class 但不确定如何映射它的情况。这是我的案例。
基础实体:
public class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id")
private Long id;
}
BaseDto:
public class BaseDto {
private Long id;
}
用户实体:
public class User extends BaseEntity {
private String name;
private String lastName;
private String username;
private String password;
private String profilePicturePath;
}
UserDto:
public class UserDto extends BaseDto {
private String name;
private String lastName;
private String username;
private String password;
private String profilePicturePath;
}
映射器是这样的:
@Mapper(uses = {BaseMapper.class})
public interface UserMapper {
User userDtoToUser(UserDto userDto);
UserDto userToUserDto(User user);
}
基础映射器:
@Mapper
public interface BaseMapper {
BaseEntity dtoToEntity(BaseDto baseDto);
BaseDto entityToDto(BaseEntity baseEntity);
}
问题是我没有映射 ID 属性。
感谢您的宝贵时间。
编辑:
没有显示错误,在映射器实现(生成的代码)中没有针对该 ID 的映射:
@Override
public User userDtoToUser(UserDto userDto) {
if ( userDto == null ) {
return null;
}
UserBuilder user = User.builder();
user.name( userDto.getName() );
user.lastName( userDto.getLastName() );
user.username( userDto.getUsername() );
user.password( userDto.getPassword() );
user.profilePicturePath( userDto.getProfilePicturePath() );
return user.build();
}
我猜(因为你没有输入 buider
代码)问题是你的构建器 class 不包含父 class 字段。 MapStruct 在为映射器生成代码时做了一些假设。来自 documentation -
The default implementation of the BuilderProvider assumes the
following:
- 该类型有一个无参数的 public 静态构建器创建方法
那 returns 一个建设者。因此,例如 Person 有一个 public static
returns PersonBuilder.
的方法
- 构建器类型有一个无参数的public方法(构建方法)
returns 正在构建的类型 在我们的示例 PersonBuilder 中有一个
方法返回 Person.
- 如果有多个构建方法,MapStruct 将寻找一个
称为构建的方法,如果存在这样的方法,则将使用它,
否则会产生编译错误。
如果你使用的是 Lombok,你可以使用 @SuperBuilder
as -
来解决这个问题
@SuperBuilder
@Getter
@ToString
public class UserDto extends BaseDto {
private String name;
private String lastName;
private String username;
private String password;
private String profilePicturePath;
}
@Getter
@SuperBuilder
class BaseDto {
private Long id;
}
@SuperBuilder
@Getter
@ToString
public class User extends BaseEntity {
private String name;
private String lastName;
private String username;
private String password;
private String profilePicturePath;
}
@Setter
@Getter
@SuperBuilder
class BaseEntity {
private Long id;
}
并且生成的可能看起来像 -
@Override
public User userDtoToUser(UserDto userDto) {
if ( userDto == null ) {
return null;
}
UserBuilder<?, ?> user = User.builder();
user.id( userDto.getId() );
user.name( userDto.getName() );
user.lastName( userDto.getLastName() );
user.username( userDto.getUsername() );
user.password( userDto.getPassword() );
user.profilePicturePath( userDto.getProfilePicturePath() );
return user.build();
}
关于 mapStruct 的问题。我遇到过从基本实体扩展 class 但不确定如何映射它的情况。这是我的案例。
基础实体:
public class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id")
private Long id;
}
BaseDto:
public class BaseDto {
private Long id;
}
用户实体:
public class User extends BaseEntity {
private String name;
private String lastName;
private String username;
private String password;
private String profilePicturePath;
}
UserDto:
public class UserDto extends BaseDto {
private String name;
private String lastName;
private String username;
private String password;
private String profilePicturePath;
}
映射器是这样的:
@Mapper(uses = {BaseMapper.class})
public interface UserMapper {
User userDtoToUser(UserDto userDto);
UserDto userToUserDto(User user);
}
基础映射器:
@Mapper
public interface BaseMapper {
BaseEntity dtoToEntity(BaseDto baseDto);
BaseDto entityToDto(BaseEntity baseEntity);
}
问题是我没有映射 ID 属性。
感谢您的宝贵时间。
编辑:
没有显示错误,在映射器实现(生成的代码)中没有针对该 ID 的映射:
@Override
public User userDtoToUser(UserDto userDto) {
if ( userDto == null ) {
return null;
}
UserBuilder user = User.builder();
user.name( userDto.getName() );
user.lastName( userDto.getLastName() );
user.username( userDto.getUsername() );
user.password( userDto.getPassword() );
user.profilePicturePath( userDto.getProfilePicturePath() );
return user.build();
}
我猜(因为你没有输入 buider
代码)问题是你的构建器 class 不包含父 class 字段。 MapStruct 在为映射器生成代码时做了一些假设。来自 documentation -
The default implementation of the BuilderProvider assumes the following:
- 该类型有一个无参数的 public 静态构建器创建方法 那 returns 一个建设者。因此,例如 Person 有一个 public static returns PersonBuilder. 的方法
- 构建器类型有一个无参数的public方法(构建方法) returns 正在构建的类型 在我们的示例 PersonBuilder 中有一个 方法返回 Person.
- 如果有多个构建方法,MapStruct 将寻找一个 称为构建的方法,如果存在这样的方法,则将使用它, 否则会产生编译错误。
如果你使用的是 Lombok,你可以使用 @SuperBuilder
as -
@SuperBuilder
@Getter
@ToString
public class UserDto extends BaseDto {
private String name;
private String lastName;
private String username;
private String password;
private String profilePicturePath;
}
@Getter
@SuperBuilder
class BaseDto {
private Long id;
}
@SuperBuilder
@Getter
@ToString
public class User extends BaseEntity {
private String name;
private String lastName;
private String username;
private String password;
private String profilePicturePath;
}
@Setter
@Getter
@SuperBuilder
class BaseEntity {
private Long id;
}
并且生成的可能看起来像 -
@Override
public User userDtoToUser(UserDto userDto) {
if ( userDto == null ) {
return null;
}
UserBuilder<?, ?> user = User.builder();
user.id( userDto.getId() );
user.name( userDto.getName() );
user.lastName( userDto.getLastName() );
user.username( userDto.getUsername() );
user.password( userDto.getPassword() );
user.profilePicturePath( userDto.getProfilePicturePath() );
return user.build();
}