mapstruct 实体转换及List转换,@Mapper注解转换 您所在的位置:网站首页 user_errors时间 mapstruct 实体转换及List转换,@Mapper注解转换

mapstruct 实体转换及List转换,@Mapper注解转换

2023-09-13 21:59| 来源: 网络整理| 查看: 265

  本文参考 https://blog.csdn.net/u012373815/article/details/88367456  主要是为了自己使用方便查询。 这些都是我平时用到了,大家有什么好方法或者有什么更多知识,希望大家不吝赐教

开发中,我们经常需要将PO转DTO、DTO转PO等一些实体间的转换。比较出名的有BeanUtil 和ModelMapper等,它们使用简单,但是在稍显复杂的业务场景下力不从心。MapStruct这个插件可以用来处理domin实体类与model类的属性映射,可配置性强。只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了复杂繁琐的映射实现。MapStruct官网地址:http://mapstruct.org/

本文类型简单包含四方面:

(1)属性名称不对应

(2)list集合转换

(3)字段类型不对应

(4)多个来源实体转换成一个参数实体

引入依赖 org.mapstruct mapstruct-processor 1.5.5.Final provided org.mapstruct mapstruct-jdk8 1.5.5.Final provided

 

需求

我们假设有学生student 类 需要转换成 用户 user 类,将学生信息存入用户信息库

此时Student 类内容如下:

public class Student { private Integer id; private String name; private Integer age; private String sex;//setters, getters, toString() 方法此处省略不写,但是实际开发需要写的哦 }

 

此时User 类内容如下

public class User { private Integer id; private String name; private Integer age; private String sex;//setters, getters, toString() 方法此处省略不写,但是实际开发需要写的哦 }

 

普通转换model

此时 Student 和 User 的属性名字都相同那么转换接口就是

 

import org.mapstruct.Mapper; @Mapper(componentModel = "spring") public interface UserMapping { /** * Student 转化为 User * @param Student * @return */ User studentToUser(Student student); }

程序运行前要先编译 mvn clean compile , 从而mapstruct框架生成UserMappingImpl 实现类。

特殊转换model

(1)属性名称不对应,如果 User 和 Student 的属性名称不对应例如:

此时Student 类内容如下:

public class Student { private Integer id; private String sname; private Integer age; private String sex; //setters, getters, toString() 方法此处省略不写,但是实际开发需要写的哦 }

 

 此时User 类内容如下:

public class User { private Integer id; private String uname; private Integer age; private String sex; //setters, getters, toString() 方法此处省略不写,但是实际开发需要写的哦 }

那么转换接口为

import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; @Mapper(componentModel = "spring") public interface UserMapping { /** * Student 转化为 User * @param Student * @return */ @Mappings({ @Mapping(target = "uname", source = "sname") // 多个属性不对应可以用 "," 隔开编写多个@Mapping // ,@Mapping(target = "uname", source = "sname") }) User studentToUser(Student student); }  

(2) 转换集合list当user 和 student 都是集合形式list 时应当如下转换转化 List 集合时必须有 实体转化,因为在实现中,List 转换是 for循环调用 实体转化的。所以当属性名不对应时,应该在 实体转化进行 @Mappings 的属性名映射配置,然后list的转换也会继承这和属性的映射。

例如 属性名相同

import org.mapstruct.Mapper; @Mapper(componentModel = "spring") public interface UserMapping { /** * Student 转化为 User * @param Student * @return */ User studentToUser(Student student); /** * Students 转化为 Users * @param Students * @return */ List studentsToUsers(List students);

属性名不同:

import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; @Mapper(componentModel = "spring") public interface UserMapping { /** * Student 转化为 User * @param Student * @return */ @Mappings({ @Mapping(target = "uname", source = "sname") // 多个属性不对应可以用 "," 隔开编写多个@Mapping // ,@Mapping(target = "uname", source = "sname") }) User studentToUser(Student student); /** * 此时 studentsToUsers 的实现为循环调用 studentToUser 并继承了 studentToUser 的属性映射 * Students 转化为 Users * @param Students * @return */ List studentsToUsers(List students); }

展示 自动生成的 UserMappingImpl 实现(此类为 执行 mvn clean compile 后自动生成)

@Component public class UserMappingImpl implements UserMapping { @Override public User studentToUser(student student) { if ( student == null ) { return null; } User user = new User(); User.setId(student.getId() ); User.setName(student.getName() ); // 如果配置了属性映射则为 //User.setUname(student.getSname() ); User.setSex(student.getSex() ); User.setAge(student.getAge() ); return user; } @Override public List studentsToUsers(List students) { if ( students == null ) { return null; } List list = new ArrayList(); for ( student student : students ) { list.add( studentToUser( student ) ); } return list; } }

 

(3)字段类型不对应

  字符串转时间,或者时间转字符串,都是用后面的dateFormat值为时间格式

@Mappings({ @Mapping(target = "createTime", source = "createTimeStr", dateFormat = "yyyy-MM-dd~hh:mm:ss") // 多个属性不对应可以用 "," 隔开编写多个@Mapping }) User studentToUser(Student student);

字段类型不对应,比如说user 类的sex字段类型改为boolean此时User 类内容如下:

public class User { private Integer id; private String uname; private Integer age; private boolean sex; //setters, getters, toString() 方法此处省略不写,但是实际开发需要写的哦 } Mappings中qualifiedByName属性可以取由@Named声明的名称 import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; @Mapper(componentModel = "spring") public interface UserMapping { /** * Student 转化为 User * @param Student * @return */ @Mappings({ @Mapping(target = "uname", source = "sname",qualifiedByName = "booleanToString") // 多个属性不对应可以用 "," 隔开编写多个@Mapping // ,@Mapping(target = "uname", source = "sname") }) User studentToUser(Student student);

@Named("booleanToString")default String booleanToString(boolean value){ if(value){ return "男"; } return "女"; }}

 有的时候有一个额外的转换方法多个mapping类文件都要用到,所以肯定有写一个工具类,mapping引用外部的方法

public class Utils{ @Named("booleanToString") default String booleanToString(boolean value){ if(value){ return "男"; } return "女"; } } @Mapper(componentModel = "spring",uses=Utils.class) public interface UserMapping { /** * Student 转化为 User * @param Student * @return */ @Mappings({ @Mapping(target = "uname", source = "sname",qualifiedByName = "booleanToString") })   User studentToUser(Student student); }

   也可以直接使用expression

 

@Mappings({ @Mapping(target = "uname",expression = "java(booleanToString(student.getSname()))") // 多个属性不对应可以用 "," 隔开编写多个@Mapping // ,@Mapping(target = "uname", source = "sname") })

 

 

 

 

(4) 多个来源实体转换成一个参数实体

@Mappings({ @Mapping(target = "chartName", source = "chart.name"), @Mapping(target = "title", source = "song.title"), @Mapping(target = "artistName", source = "song.artist.name"), @Mapping(target = "recordedAt", source = "song.artist.label.studio.name"), @Mapping(target = "city", source = "song.artist.label.studio.city"), @Mapping(target = "position", source = "position") }) ChartEntry map(Chart chart, Song song, Integer position);

 (5)有一些参数不是来自传入参数,而是默认是一些外部的枚举类或者常量类数据,

  就可以在mapper中声明要导入的外部枚举类或者常量类,

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE, imports = {StringUtils.class, UserConsts.class, UserStatusEnum.class })

 

@Mapping(target = "key",expression = "java( UserConsts.FULL_GIFT)"), @Mapping(target = "status",expression = "java(UserStatusEnum.VALID_STATUS_NO.getCode())"),

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有