1.什么是MapStruct
簡單來說,MapStruct 可以將某幾種類型的對象映射為另外一種類型,如將多個 DO(業務實體對象) 對象轉換為 DTO(數據傳輸對象),避免了在業務代碼內new DTO對象和不斷的進行set方法
2.如何使用MapStruct
(1)引入Maven依賴
<!--mapStruct依賴--> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-jdk8</artifactId> <version>1.2.0.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <scope>provided</scope> <version>1.2.0.Final</version> </dependency>
(2)使用
此處假設將兩個實體對象(StudentInfo,classInfo)轉換為一個DTO(StudentInfoDTO)
@Data public class StudentInfo { /** * 姓名 */ private String siName; /** * 年齡 */ private Integer siAge; /** * 所屬班級 */ private String siClassId; }
@Data public class classInfo { /** * 名稱 */ private String ciName; /** * 別名 */ private String ciNickName; /** * 樓號 */ private String ciFloor; }
@Data public class StudentInfoDTO { /** * 姓名 */ private String name; /** * 年齡 */ private Integer age; /** * 班級名稱 */ private String className; }
創建 Mapper(映射)接口,MapStruct 就會自動實現該接口
@Mapper public interface StudentInfoStruct { /** * get new mapStruct instance */ StudentInfoStruct INSTANCE = Mappers.getMapper(StudentInfoStruct.class); /** * 轉換學生信息實體 * * @return */ @Mappings({ @Mapping(source = "studentInfo.siName", target = "name"), @Mapping(source = "studentInfo.siAge", target = "age"), @Mapping(source = "classInfo.ciName", target = "className"), }) StudentInfoDTO from(ClassInfo classInfo,StudentInfo studentInfo) ; }
業務層調用代碼
classInfo,studentInfo實體 以通過邏輯實現獲得
StudentInfoDTO studentInfoDTO = StudentInfoStruct.INSTANCE.from(classInfo,studentInfo);
單個實體對象轉換DTO同理
(3)當轉換過程中有邏輯實現時,如進行余額變動或傳入單個參數過多,則需要定義的轉換 抽象類
@Mapper public abstract class UserBalanceRecordStruct { /** * get new mapStruct instance */ public static UserBalanceRecordStruct INSTANCE = Mappers.getMapper(UserBalanceRecordStruct.class); /** * 轉換余額變動記錄 * * @param balanceId 余額賬戶編號 * @param changeBalance 本次余額變動金額 * @param changeTypeId 變動類型 * @param oldBalance 變動之前余額 * @param unifiedOrderNo 統一訂單編號 * @return */ public BalanceRecordEntity from(String balanceId, BigDecimal changeBalance, String changeTypeId, BigDecimal oldBalance, String mark, String unifiedOrderNo) { BalanceRecordEntity recordEntity = new BalanceRecordEntity(); recordEntity.setUbrBalanceId(balanceId); recordEntity.setUbrChangeCount(changeBalance); recordEntity.setUbrTypeId(changeTypeId); recordEntity.setUbrChangeBefore(oldBalance); recordEntity.setUbrChangeAfter(oldBalance.add(changeBalance)); recordEntity.setUbrMark(mark); recordEntity.setUbrUnifiedNo(unifiedOrderNo); return recordEntity; } /** * 通過原始的記錄請求參數實體轉換為最新的分頁查詢記錄的請求參數實體 * * @param param 賬戶變動記錄查詢實體 * @return */ // public abstract BalanceRecordSearchParam from(BalanceRecordListParam param,String logicId); }
3.MapStruct注解
- @Mapper:注解在接口、類上,這樣 MapStruct 才會去實現該接口
- componentModel:該屬性用於指定實現類的類型,有幾個屬性:
- default:默認,不使用任何組建類型,可以通過Mappers.getMapper(Class) 方式獲取實例對象
- spring:在實現類上注解 @Component,可通過 @Autowired 方式注入
- jsr330:實現類上添加@javax.inject.Named 和@Singleton注解,可以通過 @Inject注解獲取。
- componentModel:該屬性用於指定實現類的類型,有幾個屬性:
- @Mappings:配置多個@Mapping 單個實體轉換時,如字段一致,則不需要配置
- @Mapping:配置屬性映射,若源對象屬性與目標對象名字一致,會自動映射對應屬性
- source:源屬性、target:目標屬性
- dateFormat:可將 String 到 Date 日期之間相互轉換,通過 SimpleDateFormat,該值為 SimpleDateFormat 的日期格式