开发的过程,经常会用到实体类属性映射,同时为了方便,开发者也很少自己写专门的属性赋值工具类。索性会直接使用Sprrng
提供的BeanUtils
工具类,然后在性能上和字段属性赋值上的问题,一直是为开发者所诟病的,下面直接上案例。
注意:
lombok
引入一定要在mapstruct
依赖的前面。否则会出现无法找到Setter和Getter方法的异常出现。
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- mapstruct -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.5.3.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.3.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.3.Final</version>
</dependency>
</dependencies>
引入依赖后,则进行日常较为常用的案例测试,首先附上基础代码:
User.java
@Data
public class User {
private Long id;
/**
* 情况一:时间字符串转时间对象
*/
private String birthDay;
/**
* 时间字符串转时间对象
*/
private Date happenDay;
/**
* 情况二:使用工具类指定方法进行处理字段
*/
private String ids;
/**
* 情况三:忽略字段
*/
private String ignore;
/**
* 情况四:字段对应
*/
private String label;
}
UserVo.java
@Data
public class UserVo {
private Long id;
/**
* 情况一:时间字符串转时间对象
*/
private Date birthDay;
/**
* 时间对象转时间字符串
*/
private String happenDay;
/**
* 情况二:使用工具类指定方法进行处理字段
*/
private List<String> ids;
/**
* 情况三:忽略字段
*/
private String ignore;
/**
* 情况四:字段对应
*/
private String value;
}
**注意:**这里的
Mapper
注解在mapstruct
包下,别与myBatis中的注解混淆。
UserMapper.java
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
@Mapping(target = "birthDay", dateFormat = "yyyy-MM-dd")
@Mapping(target = "happenDay", dateFormat = "yyyy-MM-dd")
@Mapping(source = "label", target = "value")
@Mapping(target = "ignore", ignore = true)
@Mapping(target = "ids", expression = "java(ConverterUtil.strToList(user.getIds()))")
UserVo UserToUserVo(User user);
}
ConverterUtil.java
public class ConverterUtil {
public static List<String> strToList(String str){
return Arrays.asList(str.split(","));
}
}
MapStructTest.java
public class MapStructTest {
public static void main(String[] args) {
// 1、创造属性
User user = new User();
user.setId(1L);
user.setBirthDay("2023-08-29");
user.setHappenDay(new Date());
user.setIds("11,22,33");
user.setIgnore("这是一个忽略字段");
user.setLabel("将label映射到value上");
// 2、测试效果
UserVo userVo = UserMapper.INSTANCE.UserToUserVo(user);
System.out.println(userVo);
}
}
下面打印显示结果:
UserVo(id=1, birthDay=Tue Aug 29 00:00:00 CST 2023, happenDay=2023-09-09,
ids=[11, 22, 33], ignore=null, value=将label映射到value上)
Process finished with exit code 0
@Mapping(target = "birthDay", dateFormat = "yyyy-MM-dd")
@Mapping(target = "happenDay", dateFormat = "yyyy-MM-dd")
@Mapping(source = "label", target = "value")
@Mapping(target = "ignore", ignore = true)
@Mapping(target = "ids", expression = "java(ConverterUtil.strToList(user.getIds()))")
UserVo UserToUserVo(User user);
上文中多个Mapping
也可以替换为Mapings
写法
@Mappings({
@Mapping(target = "birthDay", dateFormat = "yyyy-MM-dd"),
@Mapping(target = "happenDay", dateFormat = "yyyy-MM-dd"),
@Mapping(source = "label", target = "value"),
@Mapping(target = "ignore", ignore = true),
@Mapping(target = "ids", expression ="java(ConverterUtil.strToList(user.getIds()))")})
UserVo UserToUserVo(User user);
无论是时间字符串转时间对象,还是时间对象转时间字符串都需要补充转换的时间格式
// birthDay有 string 转 date
@Mapping(target = "birthDay", dateFormat = "yyyy-MM-dd")
// happenDay有 date 转 string
@Mapping(target = "happenDay", dateFormat = "yyyy-MM-dd")
// boolean ignore() default false;
@Mapping(target = "ignore", ignore = true)
ConverterUtil .class
工具类
public class ConverterUtil {
public static List<String> strToList(String str){
return Arrays.asList(str.split(","));
}
}
使用格式
@Mapping(target = "ids", expression = "java(ConverterUtil.strToList(user.getIds()))")
UserVo UserToUserVo(User user);
// User的label 映射到 UserVo的value
@Mapping(source = "label", target = "value")
UserVo UserToUserVo(User user);
以上就是笔者目前在项目所用的一些记实,如果想了解更多,笔者找到一份比较详细的文章,用来参考
MapStruct之@Mapping注解的用法