日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
代碼簡潔之道:對(duì)象轉(zhuǎn)換神器MapStruct

?前言

在我們?nèi)粘i_發(fā)的程序中,為了各層之間解耦,一般會(huì)定義不同的對(duì)象用來在不同層之間傳遞數(shù)據(jù),比如xxxDTO、xxxVO、xxxQO,當(dāng)在不同層之間傳輸數(shù)據(jù)時(shí),不可避免地經(jīng)常需要將這些對(duì)象進(jìn)行相互轉(zhuǎn)換。

成都創(chuàng)新互聯(lián)自2013年起,先為臨夏等服務(wù)建站,臨夏等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為臨夏企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

今天給大家介紹一個(gè)對(duì)象轉(zhuǎn)換工具M(jìn)apStruct,代碼簡潔安全、性能高,強(qiáng)烈推薦。

MapStruct簡介

MapStruct是一個(gè)代碼生成器,它基于約定優(yōu)于配置,極大地簡化了Java Bean類型之間映射的實(shí)現(xiàn)。特點(diǎn)如下:

  • 基于注解。
  • 在編譯期自動(dòng)生成映射轉(zhuǎn)換代碼。
  • 類型安全、高性能、無依賴性、易于理解閱讀。

MapStruct入門

1. 引入依賴

這里使用Gradle構(gòu)建;

dependencies {
implementation 'org.mapstruct:mapstruct:1.4.2.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}

2. 需要轉(zhuǎn)換的對(duì)象

創(chuàng)建兩個(gè)示例對(duì)象(e.g. 將Demo對(duì)象轉(zhuǎn)換為DemoDto對(duì)象);

/**
* 源對(duì)象
*/
@Data
public class Demo {
private Integer id;
private String name;
}

/**
* 目標(biāo)對(duì)象
*/
@Data
public class DemoDto {
private Integer id;
private String name;
}

3. 創(chuàng)建轉(zhuǎn)換器

只需要?jiǎng)?chuàng)建一個(gè)轉(zhuǎn)換器接口類,并在類上添加 @Mapper 注解即可(官方示例推薦以 xxxMapper 格式命名轉(zhuǎn)換器名稱);

@Mapper
public interface DemoMapper {
//使用Mappers工廠獲取DemoMapper實(shí)現(xiàn)類
DemoMapper INSTANCE = Mappers.getMapper(DemoMapper.class);
//定義接口方法,參數(shù)為來源對(duì)象,返回值為目標(biāo)對(duì)象
DemoDto toDemoDto(Demo demo);
}

4. 驗(yàn)證

public static void main(String[] args) {
Demo demo = new Demo();
demo.setId(111);
demo.setName("hello");

DemoDto demoDto = DemoMapper.INSTANCE.toDemoDto(demo);

System.out.println("目標(biāo)對(duì)象demoDto為:" + demoDto);
//輸出結(jié)果:目標(biāo)對(duì)象demoDto為:DemoDto(id=111, name=hello)
}

測(cè)試結(jié)果如下:

目標(biāo)對(duì)象demoDto為:DemoDto(id=111, name=hello);

達(dá)到了我們的預(yù)期結(jié)果。

5. 自動(dòng)生成的實(shí)現(xiàn)類

為什么聲明一個(gè)接口就可以轉(zhuǎn)換對(duì)象呢?我們看一下MapStruct在編譯期間自動(dòng)生成的實(shí)現(xiàn)類:

@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2022-09-01T17:54:38+0800",
comments = "version: 1.4.2.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-7.3.jar, environment: Java 1.8.0_231 (Oracle Corporation)"
)
public class DemoMapperImpl implements DemoMapper {

@Override
public DemoDto toDemoDto(Demo demo) {
if ( demo == null ) {
return null;
}

DemoDto demoDto = new DemoDto();

demoDto.setId( demo.getId() );
demoDto.setName( demo.getName() );

return demoDto;
}
}

可以看到,MapStruct幫我們將繁雜的代碼自動(dòng)生成了,而且實(shí)現(xiàn)類中用的都是最基本的get、set方法,易于閱讀理解,轉(zhuǎn)換速度非???。

MapStruct進(jìn)階

上面的例子只是小試牛刀,下面開始展示MapStruct的強(qiáng)大之處。

(限于篇幅,這里不展示自動(dòng)生成的實(shí)現(xiàn)類和驗(yàn)證結(jié)果,大家可自行測(cè)試)。

場(chǎng)景1:屬性名稱不同、(基本)類型不同

  • 屬性名稱不同:在方法上加上@Mapping注解,用來映射屬性;
  • 屬性基本類型不同:基本類型和String等類型會(huì)自動(dòng)轉(zhuǎn)換;

關(guān)鍵字:@Mapping注解。

/**
* 來源對(duì)象
*/
@Data
public class Demo {
private Integer id;
private String name;
}

/**
* 目標(biāo)對(duì)象
*/
@Data
public class DemoDto {
private String id;
private String fullname;
}

/**
* 轉(zhuǎn)換器
*/
@Mapper
public interface DemoMapper {
DemoMapper INSTANCE = Mappers.getMapper(DemoMapper.class);

@Mapping(target = "fullname", source = "name")
DemoDto toDemoDto(Demo demo);
}

場(chǎng)景2:統(tǒng)一映射不同類型

下面例子中,time1、time2、time3都會(huì)被轉(zhuǎn)換,具體說明看下面的注釋:

/**
* 來源對(duì)象
*/
@Data
public class Demo {
private Integer id;
private String name;
/**
* time1、time2名稱相同,time3轉(zhuǎn)為time33
* 這里的time1、time2、time33都是Date類型
*/
private Date time1;
private Date time2;
private Date time3;
}

/**
* 目標(biāo)對(duì)象
*/
@Data
public class DemoDto {
private String id;
private String name;
/**
* 這里的time1、time2、time33都是String類型
*/
private String time1;
private String time2;
private String time33;
}

/**
* 轉(zhuǎn)換器
*/
@Mapper
public interface DemoMapper {
DemoMapper INSTANCE = Mappers.getMapper(DemoMapper.class);

@Mapping(target = "time33", source = "time3")
DemoDto toDemoDto(Demo demo);

//MapStruct會(huì)將所有匹配到的:
//源類型為Date、目標(biāo)類型為String的屬性,
//按以下方法進(jìn)行轉(zhuǎn)換
static String date2String(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String strDate = simpleDateFormat.format(date);
return strDate;
}
}

場(chǎng)景3:固定值、忽略某個(gè)屬性、時(shí)間轉(zhuǎn)字符串格式

一個(gè)例子演示三種用法,具體說明看注釋,很容易理解:

關(guān)鍵字:ignore、constant、dateFormat

/**
* 來源對(duì)象
*/
@Data
public class Demo {
private Integer id;
private String name;
private Date time;
}

/**
* 目標(biāo)對(duì)象
*/
@Data
public class DemoDto {
private String id;
private String name;
private String time;
}

/**
* 轉(zhuǎn)換器
*/
@Mapper
public interface DemoMapper {
DemoMapper INSTANCE = Mappers.getMapper(DemoMapper.class);

//id屬性不賦值
@Mapping(target = "id", ignore = true)
//name屬性固定賦值為“hello”
@Mapping(target = "name", constant = "hello")
//time屬性轉(zhuǎn)為yyyy-MM-dd HH:mm:ss格式的字符串
@Mapping(target = "time", dateFormat = "yyyy-MM-dd HH:mm:ss")
DemoDto toDemoDto(Demo demo);
}

場(chǎng)景4:為某個(gè)屬性指定轉(zhuǎn)換方法

場(chǎng)景2中,我們是按照某個(gè)轉(zhuǎn)換方法,統(tǒng)一將一種類型轉(zhuǎn)換為另外一種類型;而下面這個(gè)例子,是為某個(gè)屬性指定方法:

關(guān)鍵字:@Named注解、qualifiedByName

/**
* 來源對(duì)象
*/
@Data
public class Demo {
private Integer id;
private String name;
}

/**
* 目標(biāo)對(duì)象
*/
@Data
public class DemoDto {
private String id;
private String name;
}

/**
* 轉(zhuǎn)換器
*/
@Mapper
public interface DemoMapper {
DemoMapper INSTANCE = Mappers.getMapper(DemoMapper.class);

//為name屬性指定@Named為convertName的方法進(jìn)行轉(zhuǎn)換
@Mapping(target = "name", qualifiedByName = "convertName")
DemoDto toDemoDto(Demo demo);

@Named("convertName")
static String aaa(String name) {
return "姓名為:" + name;
}
}

場(chǎng)景5:多個(gè)參數(shù)合并為一個(gè)對(duì)象

如果參數(shù)為多個(gè)的話,@Mapping注解中的source就要指定是哪個(gè)參數(shù)了,用點(diǎn)分隔:

關(guān)鍵字:點(diǎn)(.)

/**
* 來源對(duì)象
*/
@Data
public class Demo {
private Integer id;
private String name;
}

/**
* 目標(biāo)對(duì)象
*/
@Data
public class DemoDto {
private String fullname;
private String timestamp;
}

/**
* 轉(zhuǎn)換器
*/
@Mapper
public interface DemoMapper {
DemoMapper INSTANCE = Mappers.getMapper(DemoMapper.class);

//fullname屬性賦值demo對(duì)象的name屬性(注意這里.的用法)
//timestamp屬性賦值為傳入的time參數(shù)
@Mapping(target = "fullname", source = "demo.name")
@Mapping(target = "timestamp", source = "time")
DemoDto toDemoDto(Demo demo, String time);
}

場(chǎng)景6:已有目標(biāo)對(duì)象,將源對(duì)象屬性覆蓋到目標(biāo)對(duì)象

覆蓋目標(biāo)對(duì)象屬性時(shí),一般null值不覆蓋,所以需要在類上的@Mapper注解中添加屬性:nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE 代表null值不進(jìn)行賦值。

關(guān)鍵字:@MappingTarget注解、nullValuePropertyMappingStrategy

/**
* 來源對(duì)象
*/
@Data
public class Demo {
private Integer id;
private String name;
}

/**
* 目標(biāo)對(duì)象
*/
@Data
public class DemoDto {
private String id;
private String name;
}

/**
* 轉(zhuǎn)換器
*/
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE,
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public interface DemoMapper {
DemoMapper INSTANCE = Mappers.getMapper(DemoMapper.class);

//將已有的目標(biāo)對(duì)象當(dāng)作一個(gè)參數(shù)傳進(jìn)來
DemoDto toDemoDto(Demo demo, @MappingTarget DemoDto dto);
}

場(chǎng)景7:源對(duì)象兩個(gè)屬性合并為一個(gè)屬性

這種情況可以使用@AfterMapping注解。

關(guān)鍵字:@AfterMapping注解、@MappingTarget注解

/**
* 來源對(duì)象
*/
@Data
public class Demo {
private Integer id;
private String firstName;
private String lastName;
}

/**
* 目標(biāo)對(duì)象
*/
@Data
public class DemoDto {
private String id;
private String name;
}

/**
* 轉(zhuǎn)換器
*/
@Mapper
public interface DemoMapper {
DemoMapper INSTANCE = Mappers.getMapper(DemoMapper.class);

DemoDto toDemoDto(Demo demo);

//在轉(zhuǎn)換完成后執(zhí)行的方法,一般用到源對(duì)象兩個(gè)屬性合并為一個(gè)屬性的場(chǎng)景
//需要將源對(duì)象、目標(biāo)對(duì)象(@MappingTarget)都作為參數(shù)傳進(jìn)來,
@AfterMapping
static void afterToDemoDto(Demo demo, @MappingTarget DemoDto demoDto) {
String name = demo.getFirstName() + demo.getLastName();
demoDto.setName(name);
}
}

小結(jié)

本文介紹了對(duì)象轉(zhuǎn)換工具 MapStruct 庫,以安全、簡潔、優(yōu)雅的方式來優(yōu)化我們的轉(zhuǎn)換代碼。

從文中的示例場(chǎng)景中可以看出,MapStruct 提供了大量的功能和配置,使我們可以快捷的創(chuàng)建出各種或簡單或復(fù)雜的映射器。


名稱欄目:代碼簡潔之道:對(duì)象轉(zhuǎn)換神器MapStruct
文章位置:http://www.5511xx.com/article/codppej.html