欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)MapStruct對象轉(zhuǎn)換的示例代碼

 更新時間:2024年12月06日 10:34:27   作者:scj1022  
本文主要介紹了MapStruct在Java中的對象轉(zhuǎn)換使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、基本使用

1、Maven 引入

<properties>
    <lombok.version>1.18.30</lombok.version>
    <mapstruct.version>1.4.1.Final</mapstruct.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${mapstruct.version}</version>
    </dependency>

    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>${mapstruct.version}</version>
    </dependency>
</dependencies>

2、基本使用

待轉(zhuǎn)換的類

@Data
@Builder
public class UserDTO {
    private Long id;
    private Integer age;
    private String name;
}

轉(zhuǎn)換目標(biāo)類

@Data
public class UserVO {
    private Long id;
    private Integer age;
    private String name;
}

轉(zhuǎn)換器

import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

@Mapper
public interface Converter {
    // 后續(xù)通過 INSTANT 調(diào)用轉(zhuǎn)換方法
    Converter INSTANT = Mappers.getMapper(Converter.class);

    UserVO convert(UserDTO userDTO);
}

使用示例

public class Test {
    public static void main(String[] args) {
        UserDTO userDTO = UserDTO.builder().id(1L).age(18).name("scj").build();
        UserVO userVO = Converter.INSTANT.convert(userDTO);
        System.out.println(userVO);
    }
}

輸出結(jié)果

UserVO(id=1, age=18, name=scj)

可以看到在 target 生成 轉(zhuǎn)換器的實(shí)現(xiàn)類,并使用 get 和 set 進(jìn)行轉(zhuǎn)換,所以性能很高。

在這里插入圖片描述

3、Spring Bean

MapStruct提供了依賴注入的機(jī)制,讓我們能夠在Spring的環(huán)境下,更優(yōu)雅的獲得Converter。

轉(zhuǎn)換器

import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

@Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
public interface Converter {
    UserVO convert(UserDTO userDTO);
}

使用示例

@RestController
public class TestController {
    
    // 直接注入使用
    @Autowired
    private Converter converter;

    @GetMapping("/test")
    public void mapstructTest() {
        UserDTO userDTO = UserDTO.builder().id(1L).age(18).name("scj").build();
        UserVO userVO = converter.convert(userDTO);
        System.out.println(userVO);
    }
}

輸出結(jié)果

UserVO(id=1, age=18, name=scj)

可以看到 target 中生成的實(shí)現(xiàn)類交給 Spring容器 管理了

在這里插入圖片描述

二、類型一致的場景

1、字段名不一致

字段名不同,通過 target 和 source 屬性指定映射關(guān)系(字段名一致可以省略)

轉(zhuǎn)換器

@Mapper
public interface Converter {
    Converter INSTANT = Mappers.getMapper(Converter.class);

    @Mapping(target = "userName", source = "name")
    UserVO convert(UserDTO userDTO);
}

輸出結(jié)果

UserVO(id=1, age=18, username=scj)

2、ignore

不需要映射的字段,可以設(shè)置 ignore = true

轉(zhuǎn)換器

@Mapper
public interface Converter {
    Converter INSTANT = Mappers.getMapper(Converter.class);

    // 不需要映射的字段,指定 ignore = true
    @Mapping(target = "name", ignore = true)
    @Mapping(target = "age", ignore = true)
    UserVO convert(UserDTO userDTO);
}

輸出結(jié)果

UserVO(id=1, age=null, name=null)

3、defaultValue

通過 defaultValue 設(shè)置默認(rèn)值(僅當(dāng)源對象的該屬性值為 null 時)

轉(zhuǎn)換器

@Mapper
public interface Converter {
    Converter INSTANT = Mappers.getMapper(Converter.class);

    // 只有為 null 的才會生效
    @Mapping(target = "id", defaultValue = "1")
    @Mapping(target = "age", defaultValue = "66")
    @Mapping(target = "name", defaultValue = "zs")
    UserVO convert(UserDTO userDTO);
}

使用示例

public class Test {
    public static void main(String[] args) {
        // id = null
        UserDTO userDTO = UserDTO.builder().age(18).name("scj").build();
        UserVO userVO = Converter.INSTANT.convert(userDTO);
        System.out.println(userVO);
    }
}

輸出結(jié)果

UserVO(id=1, age=18, name=scj)

4、constant

通過 constant 為屬性設(shè)置常量值,無論源對象的該屬性值是否為 null

轉(zhuǎn)換器

@Mapper
public interface Converter {
    Converter INSTANT = Mappers.getMapper(Converter.class);

    // 只有為 null 的才會生效
    @Mapping(target = "id", constant = "6")
    @Mapping(target = "age", constant = "66")
    @Mapping(target = "name", constant = "zs")
    UserVO convert(UserDTO userDTO);
}

使用示例

public class Test {
    public static void main(String[] args) {
        UserDTO userDTO = UserDTO.builder().id(1).age(18).name("scj").build();
        UserVO userVO = Converter.INSTANT.convert(userDTO);
        System.out.println(userVO);
    }
}

輸出結(jié)果

UserVO(id=6, age=66, name=zs)

三、類型不一致的場景

1、默認(rèn)轉(zhuǎn)換

對于部分?jǐn)?shù)據(jù)類型,如果屬性類型不一致,會做默認(rèn)的的轉(zhuǎn)換并賦值。

包裝類 相關(guān):基本數(shù)據(jù)類型、字符串、其他包裝類

// Integer -> int
target.setIntegerValue( source.getIntegerValue() );

// Integer -> Long
target.setIntegerValue( source.getIntegerValue().longValue() );

// Integer -> Double
target.setIntegerValue( source.getIntegerValue().doubleValue() );

// Integer -> String
target.setIntegerValue( String.valueOf( source.getIntegerValue() ) );

BigDecimal 相關(guān):

// BigDecimal -> Integer/int
target.setDecimalValue( source.getDecimalValue().intValue() );

// BigDecimal -> Double/double
target.setDecimalValue( source.getDecimalValue().doubleValue() );

// BigDecimal -> String
target.setDecimalValue( source.getDecimalValue().toString() );

時間日期 相關(guān)

// Date -> LocalDateTime
target.setDateValue( LocalDateTime.ofInstant( source.getDateValue().toInstant(), ZoneId.of( "UTC" ) ) );

// LocalDateTime -> Date
target.setDateValue( Date.from( source.getDateValue().toInstant( ZoneOffset.UTC ) ) );

// Date -> String
target.setDateValue( new SimpleDateFormat().format( source.getDateValue() ) );

// LocalDateTime -> String
target.setDateValue( DateTimeFormatter.ISO_LOCAL_DATE_TIME.format( source.getDateValue() ) );

枚舉 相關(guān)

// Enum -> String
target.setEnumValue( source.getEnumValue().name() );

String 相關(guān)

// String -> Long/long
target.setStringValue( Long.parseLong( source.getStringValue() ) );

// String -> BigDecimal
target.setStringValue( new BigDecimal( source.getStringValue() ) );

// String -> Date
target.setStringValue( new SimpleDateFormat().parse( source.getStringValue() ) );

// String -> LocalDateTime
target.setStringValue( LocalDateTime.parse( source.getStringValue() ) );

// String -> Enum
target.setEnumValue( Enum.valueOf( Source.CustomEnum.class, source.getEnumValue() ) );

2、numberFormat

數(shù)字類型 轉(zhuǎn)換為 字符串 時,可以通過 numberFormat 屬性指定 格式

@Mapper
public interface Converter {
    Converter INSTANT = Mappers.getMapper(Converter.class);

    @Mapping(target = "integerValue", source = "integerValue", numberFormat = "#,##0")
    @Mapping(target = "doubleValue", source = "doubleValue", numberFormat = "#0.00")
    @Mapping(target = "decimalValue", source = "decimalValue", numberFormat = "#%")
    Target convert(Source source);
}
  • #,##0:表示數(shù)字使用千位分隔符。例如,1234567 將被格式化為 1,234,567
  • #0.00:表示數(shù)字保留兩位小數(shù)。例如,666.666 將被格式化為 666.67。
  • #%:表示將數(shù)字視為百分比。例如,0.75 將被格式化為 75%。

3、dateFormat

時間日期 轉(zhuǎn)換為 字符串 時,可以通過 dateFormat 屬性指定 pattern

待轉(zhuǎn)換的類

@Data
public class Source {
    private Date dateValue = new Date();
    private LocalDateTime localDateTimeValue = LocalDateTime.now();
}

轉(zhuǎn)換目標(biāo)類

@Data
public class Target {
    private String dateValue;
    private String localDateTimeValue;
}

轉(zhuǎn)換器

@Mapper
public interface Converter {
    Converter INSTANT = Mappers.getMapper(Converter.class);

    @Mapping(target = "dateValue", source = "dateValue", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @Mapping(target = "localDateTimeValue", source = "localDateTimeValue", dateFormat = "yyyy-MM-dd HH:mm:ss")
    Target convert(Source source);
}

輸出結(jié)果

Target(dateValue=2024-09-26 19:27:41, localDateTimeValue=2024-09-26 19:27:41)

4、枚舉值處理

待轉(zhuǎn)換的類

@Data
public class Source {
    private SexEnum sexEnum = SexEnum.MAN;
}

轉(zhuǎn)換目標(biāo)類

@Data
public class Target {
    private String sex;
}

轉(zhuǎn)換器

@Mapper
public interface Converter {
    Converter INSTANT = Mappers.getMapper(Converter.class);

    @Mapping(target = "sex", source = "sexEnum.desc")
    Target convert(Source source);
}

四、其他場景

1、對象嵌套(字段一致)

如果字段完全一致,會自動生成嵌套對象的 convert 方法。

待轉(zhuǎn)換的類

@Data
public class Source {
    private Long id = 1L;
    private SourceInnerClass1 inner = new SourceInnerClass1();
}

@Data
class SourceInnerClass1 {
    private Long id = 11L;
    private List<SourceInnerClass2> innerList = Collections.singletonList(new SourceInnerClass2());
}

@Data
class SourceInnerClass2 {
    private Long id = 111L;
    private String value = "inner2";
}

轉(zhuǎn)換目標(biāo)類

@Data
public class Target {
    private Long id;
    private TargetInnerClass1 inner;
}

@Data
class TargetInnerClass1 {
    private Long id;
    private List<TargetInnerClass2> innerList;
}

@Data
class TargetInnerClass2 {
    private Long id;
    private String value;
}

轉(zhuǎn)換器

@Mapper
public interface Converter {
    Converter INSTANT = Mappers.getMapper(Converter.class);

    Target convert(Source source);
}

輸出

Target(id=1, inner=TargetInnerClass1(id=11, innerList=[TargetInnerClass2(id=111, value=inner2)]))

可以看到,所有嵌套對象的屬性都做了自動映射

在這里插入圖片描述

在這里插入圖片描述

2、對象嵌套(字段不一致)

如果字段不一致,需要自己編寫對應(yīng)嵌套對象的 convert 方法,底層會自動調(diào)用。

待轉(zhuǎn)換的類

@Data
public class Source {
    private Long id;
    private SourceInnerClass1 inner;
}

@Data
class SourceInnerClass1 {
    private Long id;
    private List<SourceInnerClass2> innerList;
}

@Data
class SourceInnerClass2 {
    private Long id;
    private String value;
}

轉(zhuǎn)換目標(biāo)類

@Data
public class Target {
    private Long id0;
    private TargetInnerClass1 inner0;
}

@Data
class TargetInnerClass1 {
    private Long id1;
    private List<TargetInnerClass2> innerList1;
}

@Data
class TargetInnerClass2 {
    private Long id2;
    private String value2;
}

轉(zhuǎn)換器

@Mapper
public interface Converter {
    Converter INSTANT = Mappers.getMapper(Converter.class);

    @Mapping(target = "id0", source = "id")
    @Mapping(target = "inner0", source = "inner")
    Target convert(Source source);

    @Mapping(target = "id1", source = "id")
    @Mapping(target = "innerList1", source = "innerList")
    TargetInnerClass1 convert(SourceInnerClass1 source);

    @Mapping(target = "id2", source = "id")
    @Mapping(target = "value2", source = "value")
    TargetInnerClass2 convert(SourceInnerClass2 source);
}

使用示例

public class Test {
    public static void main(String[] args) {
        final Source source = new Source(1L, 18L, "scj", new SourceInner(1L, 18));
        final Target target = Converter.INSTANT.convert(source);
        System.out.println(target);
    }
}

輸出

Target(id0=1, inner0=TargetInnerClass1(id1=11, innerList1=[TargetInnerClass2(id2=111, value2=inner2)]))

會按需調(diào)用對應(yīng)對象的 convert 方法

在這里插入圖片描述

3、自定義轉(zhuǎn)換方法

使用 @Named 自定義轉(zhuǎn)換方法,通過 qualifiedByName 屬性指定,要和 @Named 的 value 對應(yīng)

待轉(zhuǎn)換的類

@Data
public class Target {
    private UserDTO targetUserDTO;
    private String targetUserJson;
}

轉(zhuǎn)換目標(biāo)類

@Data
public class Source {
    private String sourceUserJson;
    private UserDTO sourceUserDTO;
}

轉(zhuǎn)換器

@Mapper
public interface Convert {

    Convert INSTANCE = Mappers.getMapper(Convert.class);

    @Mapping(target = "targetUserDTO", source = "sourceUserJson", qualifiedByName = "json2DTO")
    @Mapping(target = "targetUserJson", source = "sourceUserDTO", qualifiedByName = "dto2Json")
    Target convert(Source source);

    @Named("json2DTO")
    default UserDTO json2DTO(String userJson) {
        return JSON.parseObject(userJson, UserDTO.class);
    }

    @Named("dto2Json")
    default String dto2Json(UserDTO userDTO) {
        return JSON.toJSONString(userDTO);
    }
}

轉(zhuǎn)換結(jié)果

Target(targetUserDTO=UserDTO(name=scj, age=18), targetUserJson={"age":66,"name":"zs"})

4、expression

通過 expression 可以指定 java 表達(dá)式,可以直接調(diào)用對應(yīng)的方法。

轉(zhuǎn)換器

@Mapper
public interface Convert {

    Convert INSTANCE = Mappers.getMapper(Convert.class);
    
    // 本類方法
    @Mapping(target = "targetUserDTO",  expression = "java(json2DTO(source.getSourceUserJson()))")
    // 非本類方法(類全名調(diào)用即可)
    @Mapping(target = "targetUserJson", expression = "java(com.alibaba.fastjson.JSON.toJSONString(source.getSourceUserDTO()))")
    // 枚舉
    @Mapping(target = "sex", expression = "java(source.getSexEnum().getDesc())")
    Target convert(Source source);

    default UserDTO json2DTO(String userJson) {
        return JSON.parseObject(userJson, UserDTO.class);
    }
}

轉(zhuǎn)換結(jié)果

Target(targetUserDTO=UserDTO(name=scj, age=18), targetUserJson={"age":66,"name":"zs"}, sex=男)

ConvertImpl

public class ConvertImpl implements Convert {
    @Override
    public Target convert(Source source) {
        if ( source == null ) {
            return null;
        }

        Target target = new Target();

        target.setTargetUserDTO( json2DTO(source.getSourceUserJson()) );
        target.setTargetUserJson( com.alibaba.fastjson.JSON.toJSONString(source.getSourceUserDTO()) );
        target.setSex( source.getSexEnum().getDesc() );

        return target;
    }
}

5、多個參數(shù)

待轉(zhuǎn)換的類

@Data
public class Target {

    // source1

    private String strValue1;
    private Integer intValue1;

    // source2

    private String strValue2;
    private Integer intValue2;

    // field

    private String strValue;
    private Integer intValue;

}

轉(zhuǎn)換目標(biāo)類

@Data
public class Source1 {
	private String strValue = "s1";
    private Integer intValue = 1;
}

@Data
public class Source2 {
    private String strValue = "s2";
    private Integer intValue = 2;
}

轉(zhuǎn)換器

@Mapper
public interface Convert {

    Convert INSTANCE = Mappers.getMapper(Convert.class);

    @Mapping(target = "strValue1", source = "s1.strValue")
    @Mapping(target = "intValue1", source = "s1.intValue")
    @Mapping(target = "strValue2", source = "s2.strValue")
    @Mapping(target = "intValue2", source = "s2.intValue")
    @Mapping(target = "strValue", source = "strValue")
    @Mapping(target = "intValue", source = "intValue")
    Target convert(Source1 s1, Source2 s2, String strValue, Integer intValue);
}

注意事項(xiàng):如果字段名全部沒有沖突,不需要 @Mapping,會自動對應(yīng)。

五、推薦的IDEA插件

IDEA 搜索 MapStruct Support 安裝即可,可以在使用MapStruct時獲得更加豐富代碼提示。

在這里插入圖片描述

到此這篇關(guān)于Java實(shí)現(xiàn)MapStruct對象轉(zhuǎn)換的示例代碼的文章就介紹到這了,更多相關(guān)Java MapStruct對象轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

最新評論