登錄閱讀全文 Java 實體映射工具 MapStruct 前言 1.MapStruct配置 2.原理 3.使用方法 參考鏈接

<meta name="source" content="lake">

簡介: 讓你的DO(業務實體對象),DTO(數據傳輸對象)數據轉換更簡單強大

前言

在軟件架構中,分層式結構是最常見,各層之間有其獨立且隔離的業務邏輯,也因而各層有自己的輸入輸出對象,也就是代碼中見到各種O,如DO、DTO、VO,這些數據對象之間通常都有很多相同或相近的屬性對象,數據在傳輸的過程中從一個O到另一個O,就通常需要賦值,從最初的的get/set

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">personDTO.setName(personDO.getName()); personDTO.setAge(personDO.getAge()); personDTO.setSex(personDO.getSex()); personDTO.setBirthday(personDO.getBirthday());</pre>

到後來的BeanUtils(減少了set的代碼量)

再到現在的MapStruct

1.MapStruct配置

     MapStuct的使用非常簡單,把對應的jar包引入即可。

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"><properties> <lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version> <org.mapstruct.version>1.3.0.Final</org.mapstruct.version> <org.mapstruct.processor.version>1.3.0.Final</org.mapstruct.processor.version> </properties> <dependencies> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-jdk8</artifactId> <version>{org.mapstruct.version}</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>{org.mapstruct.processor.version}</version> <scope>provided</scope> </dependency> </dependencies> <configuration> <source>{java.version}</source> <target>{java.version}</target> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>{org.mapstruct.processor.version}</version> </path> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>{lombok.version}</version> </path> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok-mapstruct-binding</artifactId> <version>${lombok-mapstruct-binding.version}</version> </path> </annotationProcessorPaths> </configuration></pre>

2.原理

 MapStruct屬於在編譯期,生成調用get/set方法進行賦值的代碼,生成對應的java文件。在編譯期間消耗少許的時間,換取運行時的高性能。

3.使用方法

先定義一個接口,按照規範我們在service或domainService下建一個converter包

通過依賴注入的方式獲取Mapper實例

@Mapper(componentModel = "spring")

3.1 對於同名同屬性的字段,無需特別聲明指定,自動轉換。

MapStructReq1

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Data @Accessors(chain = true) public class MapStructReq1 { private Integer id; private String name; @JsonFormat(pattern = "yyyy-MM-dd") private Date updateTime; }</pre>

MapStructResp1:

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Data @Accessors(chain = true) public class MapStructResp1 { private Integer id; private String name; @JsonFormat(pattern = "yyyy-MM-dd") private Date updateTime; }</pre>

converter:

serviceImpl:

controller:

調用demo1接口後,可以看到我們給MapStructReq1賦值後,成功拷貝到了MapStructResp1中返回

3.2 對於不同名相同屬性的字段,可以使用Mapping註解指定。

MapStructReq1

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Data @Accessors(chain = true) public class MapStructReq1 { private Integer id; private String name; @JsonFormat(pattern = "yyyy-MM-dd") private Date updateTime; }</pre>

MapStructResp2

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Data public class MapStructResp2 { private Integer id; private String productName; @JsonFormat(pattern = "yyyy-MM-dd") private Date updateTime; }</pre>

converter

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Mapping(source = "name", target = "productName") MapStructResp2 req1ToResp2(MapStructReq1 req);</pre>

controller:

req1中的name字段拷貝到了resp2中的productName中

3.3 支持把多個參數映射成一個類型,使用@Mapping指定即可。

converter:

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"> @Mapping(source = "req1.id", target = "id") @Mapping(source = "req2.productName", target = "name") @Mapping(source = "req1.updateTime", target = "updateTime") MapStructResp1 req1And2ToResp1(MapStructReq1 req1, MapStructReq2 req2);</pre>

controller:

將req1中的id,req2中的name拷貝到了resp1中

3.4 對於基礎數據類型會進行自動隱式的轉換

如int、long、String,Integer、Long等。

req3

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Data @Accessors(chain = true) public class MapStructReq3 { private String id; private int name; @JsonFormat(pattern = "yyyy-MM-dd") private Date updateTime; }</pre>

resp1:

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Data @Accessors(chain = true) public class MapStructResp1 { private Integer id; private String name; @JsonFormat(pattern = "yyyy-MM-dd") private Date updateTime; }</pre>

converter:

controller:

String 類型的id轉爲了int型,int型的name轉爲了String型

3.5 集合的拷貝

req5

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Data @Accessors(chain = true) public class MapStructReq5 { private Integer id; private MapStructReq1 target; private List<MapStructReq1> list; }</pre>

resp5

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Data @Accessors(chain = true) public class MapStructResp5 { private Integer id; private MapStructResp1 target; private List<MapStructResp1> list; }</pre>

converter:

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">List<MapStructResp1> req1ListToResp1List(List<MapStructReq1> req1List);</pre>

controller:

3.6 嵌套對象的拷貝

converter:

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">MapStructResp5 req5ToResp5(MapStructReq5 req);</pre>

controller:

給target賦值爲req1,給list賦值爲4個不同名字的req1

3.7 使用java表達式進行映射

對於複雜的映射,允許使用java表達式實現字段的映射。

注意要導入使用到的類。

req6

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Data @Accessors(chain = true) public class MapStructReq6 { private Integer id; private int price1; private int price2; }</pre>

resp6

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Data @Accessors(chain = true) public class MapStructResp6 { private Integer id; private int price1; private int price2; }</pre>

DemoUtils

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">public class DemoUtils { public static int add(int val1, int val2) { return val1 + val2; } }</pre>

converter:

<pre class="cm-s-default" style="color: rgb(55, 61, 65); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">@Mapper(componentModel = "spring", imports = {DemoUtils.class})//導入java表達式使用的類,導入多個類在{}中用逗號分隔 public interface MapStructConverterDemo1 { /** * 使用java表達式進行映射 * @param req * @return */ @Mapping(target = "price1", expression = "java(req.getPrice1() + req.getPrice2())")//直接相加 @Mapping(target = "price2", expression = "java(DemoUtils.add(req.getPrice1(), req.getPrice2()))")//使用工具類處理 MapStructResp6 req6ToResp6(MapStructReq6 req); }</pre>

controller:

參考鏈接

https://www.cnblogs.com/gotten/p/13052911.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章