最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中基于注解的代碼生成工具M(jìn)apStruct映射使用詳解

 更新時(shí)間:2025年02月10日 09:04:49   作者:Andya  
MapStruct?作為一個(gè)基于注解的代碼生成工具,為我們提供了一種更加優(yōu)雅、高效的解決方案,本文主要為大家介紹了它的具體使用,感興趣的可以了解下

介紹

在 Java 開(kāi)發(fā)中,我們經(jīng)常需要在不同的 Java Bean 之間進(jìn)行數(shù)據(jù)映射,比如從實(shí)體類(lèi)(Entity)到數(shù)據(jù)傳輸對(duì)象(DTO)的轉(zhuǎn)換。傳統(tǒng)的做法是手動(dòng)編寫(xiě)大量的 setter 和 getter 方法來(lái)完成屬性的賦值,這種方式不僅繁瑣,而且容易出錯(cuò)。MapStruct 作為一個(gè)基于注解的代碼生成工具,為我們提供了一種更加優(yōu)雅、高效的解決方案。它在編譯時(shí)自動(dòng)生成映射代碼,避免了運(yùn)行時(shí)反射帶來(lái)的性能開(kāi)銷(xiāo),同時(shí)保證了類(lèi)型安全。

優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

  • 高性能:MapStruct 在編譯階段生成映射代碼,運(yùn)行時(shí)直接調(diào)用這些代碼,避免了反射的使用,從而顯著提高了性能。
  • 類(lèi)型安全:由于映射代碼是在編譯時(shí)生成的,編譯器會(huì)對(duì)類(lèi)型進(jìn)行檢查,因此可以在編譯階段發(fā)現(xiàn)類(lèi)型不匹配等錯(cuò)誤,避免了運(yùn)行時(shí)異常。
  • 代碼簡(jiǎn)潔:使用 MapStruct 只需要定義映射接口和使用注解進(jìn)行配置,無(wú)需手動(dòng)編寫(xiě)大量的映射邏輯,大大減少了代碼量,提高了開(kāi)發(fā)效率。

缺點(diǎn)

  • 學(xué)習(xí)成本:需要學(xué)習(xí) MapStruct 提供的各種注解及其使用方法,對(duì)于初學(xué)者來(lái)說(shuō)可能有一定的學(xué)習(xí)曲線。
  • 依賴管理:需要在項(xiàng)目中引入 MapStruct 的相關(guān)依賴,增加了項(xiàng)目的依賴管理復(fù)雜度。

核心注解及詳細(xì)使用語(yǔ)法說(shuō)明

@Mapper

  • 作用:用于標(biāo)記一個(gè)接口為映射接口,MapStruct 會(huì)在編譯時(shí)為該接口生成具體的實(shí)現(xiàn)類(lèi)。
  • 使用語(yǔ)法
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

@Mapper
public interface UserMapper {
    // 通過(guò) Mappers.getMapper 方法獲取映射接口的實(shí)例
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    // 定義從 UserEntity 到 UserDTO 的映射方法
    UserDTO toDTO(UserEntity entity);
    // 定義從 UserDTO 到 UserEntity 的映射方法
    UserEntity toEntity(UserDTO dto);
}

@Mapping

  • 作用:用于指定源對(duì)象和目標(biāo)對(duì)象之間的屬性映射關(guān)系,當(dāng)源對(duì)象和目標(biāo)對(duì)象的屬性名不一致時(shí),可以使用該注解進(jìn)行顯式映射。
  • 使用語(yǔ)法
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    // 使用 @Mapping 注解指定 entityId 映射到 id,entityName 映射到 name
    @Mapping(source = "entityId", target = "id")
    @Mapping(source = "entityName", target = "name")
    UserDTO toDTO(UserEntity entity);

    // 反向映射
    @Mapping(source = "id", target = "entityId")
    @Mapping(source = "name", target = "entityName")
    UserEntity toEntity(UserDTO dto);
}

@Mappings

  • 作用:@Mappings 是 @Mapping 的集合形式,用于一次性指定多個(gè)屬性映射關(guān)系。
  • 使用語(yǔ)法
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    @Mappings({
        @Mapping(source = "entityId", target = "id"),
        @Mapping(source = "entityName", target = "name")
    })
    UserDTO toDTO(UserEntity entity);

    @Mappings({
        @Mapping(source = "id", target = "entityId"),
        @Mapping(source = "name", target = "entityName")
    })
    UserEntity toEntity(UserDTO dto);
}

@Context

  • 作用:用于在映射過(guò)程中傳遞上下文信息,比如一些輔助對(duì)象,這些對(duì)象可以在映射方法中使用。
  • 使用語(yǔ)法
import org.mapstruct.Mapper;
import org.mapstruct.Context;
import org.mapstruct.factory.Mappers;
import java.util.Locale;

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    // 使用 @Context 注解傳遞 Locale 對(duì)象作為上下文信息
    UserDTO toDTO(UserEntity entity, @Context Locale locale);
}

@AfterMapping

  • 作用:用于在映射完成后執(zhí)行自定義的邏輯,比如對(duì)目標(biāo)對(duì)象的某些屬性進(jìn)行額外的處理。
  • 使用語(yǔ)法
import org.mapstruct.Mapper;
import org.mapstruct.AfterMapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers;

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    UserDTO toDTO(UserEntity entity);

    // 使用 @AfterMapping 注解定義映射完成后的自定義邏輯
    @AfterMapping
    default void afterMapping(@MappingTarget UserDTO dto, UserEntity entity) {
        // 將源對(duì)象的 firstName 和 lastName 拼接后賦值給目標(biāo)對(duì)象的 fullName 屬性
        dto.setFullName(entity.getFirstName() + " " + entity.getLastName());
    }
}

Demo示例

公共基本類(lèi)定義

import lombok.Data;

// 用戶實(shí)體類(lèi)
@Data
public class UserEntity {
    private Long id;
    private String name;
    private Integer age;
    private String firstName;
    private String lastName;
    private AddressEntity address;
    private Long entityId;
    private String entityName;
}

// 用戶數(shù)據(jù)傳輸對(duì)象類(lèi)
@Data
public class UserDTO {
    private Long id;
    private String name;
    private Integer age;
    private String fullName;
    private AddressDTO address;
    private Long entityId;
    private String entityName;
}

// 地址實(shí)體類(lèi)
@Data
public class AddressEntity {
    private String street;
    private String city;
}

// 地址數(shù)據(jù)傳輸對(duì)象類(lèi)
@Data
public class AddressDTO {
    private String street;
    private String city;
}

簡(jiǎn)單映射示例

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

@Mapper
public interface UserMapper {
    // 獲取映射接口的實(shí)例
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    // 從 UserEntity 到 UserDTO 的映射方法
    UserDTO toDTO(UserEntity entity);
    // 從 UserDTO 到 UserEntity 的映射方法
    UserEntity toEntity(UserDTO dto);
}

// 測(cè)試代碼
public class MainSimpleMapping {
    public static void main(String[] args) {
        UserEntity userEntity = new UserEntity();
        userEntity.setId(1L);
        userEntity.setName("John");
        userEntity.setAge(25);

        // 使用映射接口的實(shí)例進(jìn)行映射
        UserDTO userDTO = UserMapper.INSTANCE.toDTO(userEntity);
        System.out.println("簡(jiǎn)單映射示例結(jié)果:");
        System.out.println("UserDTO: id=" + userDTO.getId() + ", name=" + userDTO.getName() + ", age=" + userDTO.getAge());
    }
}

輸出結(jié)果:

簡(jiǎn)單映射示例結(jié)果:
UserDTO: id=1, name=John, age=25

字段名不一致的映射示例

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

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    @Mapping(source = "entityId", target = "id")
    @Mapping(source = "entityName", target = "name")
    UserDTO toDTO(UserEntity entity);

    @Mapping(source = "id", target = "entityId")
    @Mapping(source = "name", target = "entityName")
    UserEntity toEntity(UserDTO dto);
}

// 測(cè)試代碼
public class MainFieldNameMismatch {
    public static void main(String[] args) {
        UserEntity userEntity = new UserEntity();
        userEntity.setEntityId(1L);
        userEntity.setEntityName("John");
        userEntity.setAge(25);

        UserDTO userDTO = UserMapper.INSTANCE.toDTO(userEntity);
        System.out.println("字段名不一致映射示例結(jié)果:");
        System.out.println("UserDTO: id=" + userDTO.getId() + ", name=" + userDTO.getName() + ", age=" + userDTO.getAge());
    }
}

輸出結(jié)果:

字段名不一致映射示例結(jié)果:
UserDTO: id=1, name=John, age=25

嵌套對(duì)象映射示例

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

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    UserDTO toDTO(UserEntity entity);
    UserEntity toEntity(UserDTO dto);

    AddressDTO toDTO(AddressEntity entity);
    AddressEntity toEntity(AddressDTO dto);
}

// 測(cè)試代碼
public class MainNestedObjectMapping {
    public static void main(String[] args) {
        AddressEntity addressEntity = new AddressEntity();
        addressEntity.setStreet("123 Main St");
        addressEntity.setCity("New York");

        UserEntity userEntity = new UserEntity();
        userEntity.setId(1L);
        userEntity.setName("John");
        userEntity.setAddress(addressEntity);

        UserDTO userDTO = UserMapper.INSTANCE.toDTO(userEntity);
        System.out.println("嵌套對(duì)象映射示例結(jié)果:");
        System.out.println("UserDTO: id=" + userDTO.getId() + ", name=" + userDTO.getName());
        System.out.println("AddressDTO: street=" + userDTO.getAddress().getStreet() + ", city=" + userDTO.getAddress().getCity());
    }
}

輸出結(jié)果:

嵌套對(duì)象映射示例結(jié)果:
UserDTO: id=1, name=John
AddressDTO: street=123 Main St, city=New York

自定義映射邏輯示例

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

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    UserDTO toDTO(UserEntity entity);

    @AfterMapping
    default void afterMapping(@MappingTarget UserDTO dto, UserEntity entity) {
        dto.setFullName(entity.getFirstName() + " " + entity.getLastName());
    }
}

// 測(cè)試代碼
public class MainCustomMappingLogic {
    public static void main(String[] args) {
        UserEntity userEntity = new UserEntity();
        userEntity.setId(1L);
        userEntity.setFirstName("John");
        userEntity.setLastName("Doe");

        UserDTO userDTO = UserMapper.INSTANCE.toDTO(userEntity);
        System.out.println("自定義映射邏輯示例結(jié)果:");
        System.out.println("UserDTO: id=" + userDTO.getId() + ", fullName=" + userDTO.getFullName());
    }
}

輸出結(jié)果:

自定義映射邏輯示例結(jié)果:
UserDTO: id=1, fullName=John Doe

使用上下文示例

import org.mapstruct.Mapper;
import org.mapstruct.Context;
import org.mapstruct.factory.Mappers;
import java.util.Locale;

@Mapper
public interface UserMapper {
    UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);

    UserDTO toDTO(UserEntity entity, @Context Locale locale);

    default String localize(String value, @Context Locale locale) {
        // 根據(jù) locale 進(jìn)行本地化處理
        return value;
    }
}

// 測(cè)試代碼
public class MainWithContext {
    public static void main(String[] args) {
        UserEntity userEntity = new UserEntity();
        userEntity.setId(1L);
        userEntity.setName("John");

        Locale locale = Locale.US;
        UserDTO userDTO = UserMapper.INSTANCE.toDTO(userEntity, locale);
        System.out.println("使用上下文示例結(jié)果:");
        System.out.println("UserDTO: id=" + userDTO.getId() + ", name=" + userDTO.getName());
    }
}

輸出結(jié)果:

使用上下文示例結(jié)果:
UserDTO: id=1, name=John

通過(guò)以上示例可以看到,使用 MapStruct 能夠方便快捷地完成 Java Bean 之間的映射,同時(shí)結(jié)合 Lombok 的 @Data 注解進(jìn)一步簡(jiǎn)化了代碼。并且從輸出結(jié)果可以直觀地驗(yàn)證各個(gè)映射場(chǎng)景的正確性。

到此這篇關(guān)于Java中基于注解的代碼生成工具M(jìn)apStruct映射使用詳解的文章就介紹到這了,更多相關(guān)Java MapStruct內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 流式圖表拒絕增刪改查之框架搭建過(guò)程

    流式圖表拒絕增刪改查之框架搭建過(guò)程

    這篇文章主要為大家介紹了流式圖表拒絕增刪改查之框架搭建過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Springboot實(shí)現(xiàn)對(duì)配置文件中的明文密碼加密詳解

    Springboot實(shí)現(xiàn)對(duì)配置文件中的明文密碼加密詳解

    我們?cè)赟pringBoot項(xiàng)目當(dāng)中,會(huì)把數(shù)據(jù)庫(kù)的用戶名密碼等配置直接放在yaml或者properties文件中,這樣維護(hù)數(shù)據(jù)庫(kù)的密碼等敏感信息顯然是有一定風(fēng)險(xiǎn)的。所以本文為大家整理了對(duì)配置文件中的明文密碼加密的方法,希望對(duì)大家有所幫助
    2023-03-03
  • Nacos通過(guò)RefreshScope實(shí)現(xiàn)配置自動(dòng)更新的方式分享

    Nacos通過(guò)RefreshScope實(shí)現(xiàn)配置自動(dòng)更新的方式分享

    這篇文章主要給大家介紹了Nacos如何通過(guò)RefreshScope實(shí)現(xiàn)配置自動(dòng)更新,文中給了兩種實(shí)現(xiàn)方式供大家參考,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-09-09
  • 如何把Java程序窗口在屏幕中間顯示

    如何把Java程序窗口在屏幕中間顯示

    大家在日常Java開(kāi)發(fā)中,可能會(huì)需要把程序窗口定位在屏幕中間,那該如何操作呢,下面來(lái)一起看看。
    2016-08-08
  • Java設(shè)計(jì)模式中的裝飾者模式

    Java設(shè)計(jì)模式中的裝飾者模式

    這篇文章主要介紹了Java設(shè)計(jì)模式中的裝飾者模式,裝飾者模式即Decorator?Pattern,裝飾模式是在不必改變?cè)?lèi)文件和使用繼承的情況下,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對(duì)象的功能
    2022-07-07
  • IDEA編譯報(bào)錯(cuò): Error:(2048,1024) java: 找不到符號(hào)的解決辦法

    IDEA編譯報(bào)錯(cuò): Error:(2048,1024) java: 找不到符號(hào)的解決辦法

    這篇文章主要介紹了IDEA編譯報(bào)錯(cuò): Error:(2048,1024) java: 找不到符號(hào)的解決辦法,提供了詳細(xì)的排查步驟和代碼示例,幫助開(kāi)發(fā)者快速定位和解決該問(wèn)題,需要的朋友可以參考下
    2025-05-05
  • Java中自定義泛型方法及其應(yīng)用示例代碼

    Java中自定義泛型方法及其應(yīng)用示例代碼

    泛型方法是Java中一個(gè)強(qiáng)大的特性,它允許我們?cè)诜椒?jí)別使用類(lèi)型參數(shù),提高代碼的復(fù)用性和類(lèi)型安全性,通過(guò)本文,讀者可以學(xué)習(xí)如何定義和使用泛型方法,并了解其在處理集合、比較對(duì)象、創(chuàng)建實(shí)例等任務(wù)中的應(yīng)用,感興趣的朋友一起看看吧
    2025-02-02
  • Spring Boot + KingbaseES 連接池的實(shí)現(xiàn)步驟

    Spring Boot + KingbaseES 連接池的實(shí)現(xiàn)步驟

    本文介紹了SpringBoot+KingbaseES環(huán)境中如何選擇和配置合適的數(shù)據(jù)庫(kù)連接池,對(duì)比了DBCP、C3P0、Druid和HikariCP四大主流連接池的特點(diǎn)和配置方式,感興趣的可以了解一下
    2026-04-04
  • 詳解SpringBoot結(jié)合swagger2快速生成簡(jiǎn)單的接口文檔

    詳解SpringBoot結(jié)合swagger2快速生成簡(jiǎn)單的接口文檔

    這篇文章主要介紹了詳解SpringBoot結(jié)合swagger2快速生成簡(jiǎn)單的接口文檔,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-05-05
  • Java生成獨(dú)一無(wú)二的工單號(hào)實(shí)例

    Java生成獨(dú)一無(wú)二的工單號(hào)實(shí)例

    這篇文章主要介紹了Java生成獨(dú)一無(wú)二的工單號(hào)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-09-09

最新評(píng)論

颍上县| 阜城县| 剑河县| 津市市| 宁安市| 游戏| 莎车县| 镇雄县| 旅游| 鹰潭市| 清涧县| 闵行区| 宜良县| 乐亭县| 正阳县| 通州市| 清水县| 江都市| 德州市| 民丰县| 镇赉县| 丹江口市| 湾仔区| 瑞丽市| 视频| 淳安县| 嵩明县| 韶关市| 仁化县| 苏尼特左旗| 衢州市| 文水县| 金门县| 六安市| 邯郸县| 三台县| 靖安县| 民县| 新兴县| 科技| 玉龙|