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

使用MapStruct實(shí)現(xiàn)Java對(duì)象映射的示例代碼

 更新時(shí)間:2025年09月25日 11:06:49   作者:1candobetter  
本文主要介紹了使用MapStruct實(shí)現(xiàn)Java對(duì)象映射的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

在分層架構(gòu)的開(kāi)發(fā)中,經(jīng)常遇到以下場(chǎng)景:將 DAO 查詢出的 Entity 對(duì)象,轉(zhuǎn)換為返回給前端的 VO 對(duì)象;或者將前端傳來(lái)的 DTO 對(duì)象,轉(zhuǎn)換為要存入數(shù)據(jù)庫(kù)的 Entity 對(duì)象。

每當(dāng)兩個(gè)對(duì)象的字段很多時(shí),用get和set的方法完成“數(shù)據(jù)搬運(yùn)”的過(guò)程就比較麻煩,接下來(lái)介紹一下使用MapStruct的方法。

一、什么是 MapStruct?

MapStruct 是一個(gè) Java 注解處理器,用于在編譯時(shí)自動(dòng)生成類(lèi)型安全、高性能的對(duì)象映射代碼。 請(qǐng)注意這里的幾個(gè)關(guān)鍵詞:

編譯時(shí)生成代碼:它不是像 `BeanUtils.copyProperties` 那樣在運(yùn)行時(shí)使用反射,所以性能極高,與你手寫(xiě)的 `get/set` 代碼完全一樣。

類(lèi)型安全:它在編譯期間就會(huì)對(duì)字段類(lèi)型進(jìn)行檢查。如果源對(duì)象和目標(biāo)對(duì)象的字段類(lèi)型不兼容,編譯會(huì)直接報(bào)錯(cuò),讓你能盡早發(fā)現(xiàn)問(wèn)題。

注解驅(qū)動(dòng):你只需要定義一個(gè)簡(jiǎn)單的 Java 接口并添加注解,MapStruct 就會(huì)在幕后為你完成所有繁重的工作。

二、實(shí)戰(zhàn)演練:三步集成 MapStruct

讓我們通過(guò)一個(gè)將 `DataProductItemDto` (DTO) 轉(zhuǎn)換為 `DataProduct` (Entity) 的實(shí)例,來(lái)看看 MapStruct 的使用方法。

第一步:添加 Maven 依賴 (`pom.xml`)

這是整個(gè)集成的基礎(chǔ)。需要告訴 Maven 項(xiàng)目要使用 MapStruct,并配置好編譯器。

<!-- 1. 在 <properties> 中統(tǒng)一定義版本號(hào) -->
<properties>
    <org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
    <lombok.version>1.18.30</lombok.version>
    <lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties>
 
<!-- 2. 在 <dependencies> 中添加核心庫(kù) -->
<dependencies>
    <!-- MapStruct 核心庫(kù) -->
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${org.mapstruct.version}</version>
    </dependency>
 
    <!-- (如果使用Lombok) 這是讓 MapStruct 和 Lombok 和諧共處的關(guān)鍵 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok-mapstruct-binding</artifactId>
        <version>${lombok-mapstruct-binding.version}</version>
    </dependency>
</dependencies>
 
<!-- 3. 在 <build><plugins> 中配置注解處理器 (最關(guān)鍵的部分) -->
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <source>1.8</source> <!-- 或你的 Java 版本 -->
                <target>1.8</target> <!-- 或你的 Java 版本 -->
                <annotationProcessorPaths>
                    <!-- 必須確保 Lombok 在 MapStruct 之前執(zhí)行 -->
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>${lombok.version}</version>
                    </path>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${org.mapstruct.version}</version>
                    </path>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok-mapstruct-binding</artifactId>
                        <version>${lombok-mapstruct-binding.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

配置要點(diǎn):annotationProcessorPaths 里的順序非常重要,確保了 Lombok 先為你的類(lèi)生成 getter/setter,然后 MapStruct 才能找到并使用它們。

修改完 pom.xml 后,務(wù)必重新構(gòu)建你的 Maven 項(xiàng)目

第二步:創(chuàng)建 Mapper 接口

現(xiàn)在需要定義“翻譯規(guī)則”。你只需要?jiǎng)?chuàng)建一個(gè)接口,剩下的交給 MapStruct。

package com.cmgii.trust.third.dtcp.converter;// 建議放在專(zhuān)門(mén)的 converter 包下

import com.cmgii.trust.third.dtcp.domain.DataProduct;
import com.cmgii.trust.third.dtcp.domain.vo.respVO.DataProductItemDto;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import java.util.List;

@Mapper
public interface DataProductConverter {

    //提供一個(gè)全局唯一的翻譯官實(shí)例
    DataProductConverter INSTANCE = Mappers.getMapper(DataProductConverter.class);

    /**
     * 將單個(gè) DTO 轉(zhuǎn)換為實(shí)體。
     * MapStruct 會(huì)自動(dòng)映射所有同名、同類(lèi)型的字段。
     * 我們只需為有特殊轉(zhuǎn)換需求的字段(如日期格式)添加規(guī)則。
     * @param dto 源 DTO 對(duì)象
     * @return 轉(zhuǎn)換后的實(shí)體對(duì)象
     */
    @Mapping(source = "listTime", target = "listTime", dateFormat = "yyyy-MM-dd'T'HH:mm:ss")
    DataProduct toDataProduct(DataProductItemDto dto);

    /**
     * 將 DTO 列表轉(zhuǎn)換為實(shí)體列表。
     * MapStruct 會(huì)自動(dòng)復(fù)用上面的 toEntity 方法來(lái)處理列表中的每一個(gè)元素。
     *
     * @param dtoList 源 DTO 列表
     * @return 轉(zhuǎn)換后的實(shí)體列表
     */
    List<DataProduct> toDataProductList(List<DataProductItemDto> dtoList);
} 

1. @Mapper 注解

  • 作用:這是 MapStruct 的核心注解。它告訴 MapStruct 的代碼生成器:“嘿,這個(gè)接口不是一個(gè)普通的接口,它是一份映射規(guī)則的藍(lán)圖。請(qǐng)?jiān)诰幾g時(shí),為我自動(dòng)生成一個(gè)實(shí)現(xiàn)了這個(gè)接口的 ...Impl 類(lèi)。

2. DataProductConverter INSTANCE = ... (單例模式)

  • 作用:這是獲取 Mapper 實(shí)例的經(jīng)典方式(當(dāng)不使用 Spring 注入時(shí))。
  • Mappers.getMapper(...): 這是 MapStruct 提供的一個(gè)工廠方法,它會(huì)找到并返回 MapStruct 在編譯時(shí)為您自動(dòng)生成的那個(gè) DataProductConverterImpl 類(lèi)的單例實(shí)例。
  • 用法:在應(yīng)用的任何地方,都可以通過(guò) DataProductConverter.INSTANCE 來(lái)獲取到這個(gè)唯一的、線程安全的“翻譯官”,然后調(diào)用他的翻譯方法。

3. toDataProduct(DataProductItemDto dto) - 單個(gè)對(duì)象映射

  • 作用:定義了如何將一個(gè) DataProductItemDto 對(duì)象,轉(zhuǎn)換成一個(gè) DataProduct 對(duì)象。
  • MapStruct 的智能自動(dòng)化:DataProductItemDto 和 DataProduct 這兩個(gè)類(lèi)有大量同名、同類(lèi)型的字段。MapStruct 會(huì)自動(dòng)識(shí)別并映射這些字段,無(wú)需為它們編寫(xiě)任何 @Mapping 注解。
  • @Mapping(...) - 特殊規(guī)則定制:
    • source = "listTime", target = "listTime": source 指源對(duì)象(DTO)的屬性,target 指目標(biāo)對(duì)象(Domain)的屬性。這里兩者同名。
    • dateFormat = "yyyy-MM-dd'T'HH:mm:ss"這是最關(guān)鍵的定制規(guī)則。它告訴 MapStruct:“當(dāng)你在轉(zhuǎn)換 listTime 這個(gè)字段時(shí),請(qǐng)注意,源對(duì)象里的 listTime 是一個(gè)字符串,而目標(biāo)對(duì)象里的是一個(gè) Date。請(qǐng)你使用 "yyyy-MM-dd'T'HH:mm:ss" 這個(gè)格式,將字符串解析成 Date 對(duì)象。”
    • 這完美地解決了日期格式解析問(wèn)題,而且是以一種非常聲明式、非常優(yōu)雅的方式。

4. toDataProductList(List<DataProductItemDto> dtoList) - 集合映射

  • 作用:定義了如何將一個(gè) DataProductItemDto 的列表,轉(zhuǎn)換成一個(gè) DataProduct 的列表
  • MapStruct 的進(jìn)一步智能:MapStruct 足夠智能,當(dāng)它看到這個(gè)方法時(shí),它會(huì)發(fā)現(xiàn):“哦,我知道如何轉(zhuǎn)換單個(gè) DataProductItemDto(通過(guò) toDataProduct 方法),那轉(zhuǎn)換一個(gè)列表,我只需要對(duì)列表里的每個(gè)元素都調(diào)用一次 toDataProduct 方法就行了。”
  • 因此,不需要為這個(gè)方法編寫(xiě)任何額外的 @Mapping 注解。MapStruct 會(huì)自動(dòng)生成一個(gè)循環(huán)遍歷并逐個(gè)轉(zhuǎn)換的實(shí)現(xiàn)。

第三步:在 Service 中使用 Mapper

可以在業(yè)務(wù)邏輯中,用一行代碼替代原來(lái)繁瑣的轉(zhuǎn)換過(guò)程。

@Override
    @Transactional
    public void syncDataProducts() {
        // 1. 從第三方獲取所有數(shù)據(jù)產(chǎn)品
        List<DataProductItemDto> remoteProductsDto = cmccDtcpThirdService.selectAllDataProductList();

        // 2. 將DTO轉(zhuǎn)換為實(shí)體
        List<DataProduct> dataProducts = DataProductConverter.INSTANCE.toDataProductList(remoteProductsDto);

        // 3. 批量存入數(shù)據(jù)庫(kù)
        if (dataProducts != null && !dataProducts.isEmpty()) {
            dataProductMapper.batchInsertOrUpdate(dataProducts);
        }
    }

三、總結(jié):為什么選擇 MapStruct?

特性手動(dòng) get/setBeanUtils.copyPropertiesMapStruct
性能極高較低 (運(yùn)行時(shí)反射)極高 (編譯時(shí)生成)
類(lèi)型安全編譯時(shí)運(yùn)行時(shí) (可能沉默失敗)編譯時(shí) (推薦)
代碼簡(jiǎn)潔度極好
可維護(hù)性極好

到此這篇關(guān)于使用MapStruct實(shí)現(xiàn)Java對(duì)象映射的文章就介紹到這了,更多相關(guān)MapStruct 實(shí)現(xiàn) Java 對(duì)象映射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的ClassLoader雙親委派機(jī)制詳解

    Java中的ClassLoader雙親委派機(jī)制詳解

    這篇文章主要介紹了Java中的ClassLoader雙親委派機(jī)制,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • 使用Java實(shí)現(xiàn)裁剪和壓縮PPT中的圖片

    使用Java實(shí)現(xiàn)裁剪和壓縮PPT中的圖片

    在工作中,PPT演示文稿廣泛應(yīng)用于報(bào)告、課程內(nèi)容展示以及項(xiàng)目計(jì)劃,然而,當(dāng)?PPT?文件中包含大量圖片時(shí),文件大小常常大幅增加,導(dǎo)致加載緩慢、分享困難等問(wèn)題,因此在這篇文章中,我們將詳細(xì)介紹如何使用Java實(shí)現(xiàn)裁剪和壓縮PPT中的圖片,需要的朋友可以參考下
    2026-03-03
  • Java Web中常用的分頁(yè)組件(Java端實(shí)現(xiàn))

    Java Web中常用的分頁(yè)組件(Java端實(shí)現(xiàn))

    本文通過(guò)使用場(chǎng)景分析給大家介紹了Java Web中常用的分頁(yè)組件(Java端實(shí)現(xiàn)),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-05-05
  • 解決JDBC Connection Reset的問(wèn)題分析

    解決JDBC Connection Reset的問(wèn)題分析

    這篇文章主要介紹了解決JDBC Connection Reset的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Java操作ElasticSearch的實(shí)例詳解

    Java操作ElasticSearch的實(shí)例詳解

    Elasticsearch?是一個(gè)分布式的搜索和分析引擎,廣泛用于全文搜索、日志分析等場(chǎng)景,本文將介紹如何在?Java?應(yīng)用中使用?Elasticsearch?客戶端來(lái)連接和操作?Elasticsearch?集群,希望對(duì)大家有所幫助
    2025-01-01
  • Java8新特性Stream流實(shí)例詳解

    Java8新特性Stream流實(shí)例詳解

    Stream流是數(shù)據(jù)渠道,用于操作數(shù)據(jù)源(集合、數(shù)組等)所生成的元素序列。這篇文章主要介紹了Java8新特性Stream流的相關(guān)資料,需要的朋友參考下吧
    2017-10-10
  • Java 坐標(biāo)系相互轉(zhuǎn)換方式

    Java 坐標(biāo)系相互轉(zhuǎn)換方式

    這篇文章主要介紹了Java中的坐標(biāo)系相互轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Spring 日志規(guī)范及作用

    Spring 日志規(guī)范及作用

    日志是在系統(tǒng)運(yùn)行過(guò)程中關(guān)鍵的節(jié)點(diǎn)的數(shù),這個(gè)些日志的記錄方便當(dāng)系統(tǒng)出現(xiàn)問(wèn)題方便問(wèn)題查找,這篇文章主要介紹了Spring 日志規(guī)范及作用,需要的朋友可以參考下
    2024-03-03
  • Java 正則表達(dá)式的使用實(shí)戰(zhàn)案例

    Java 正則表達(dá)式的使用實(shí)戰(zhàn)案例

    本文詳細(xì)介紹了Java正則表達(dá)式的使用方法,涵蓋語(yǔ)法細(xì)節(jié)、核心類(lèi)方法、高級(jí)特性及實(shí)戰(zhàn)案例,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友跟隨小編一起看看吧
    2025-08-08
  • springboot如何連接兩個(gè)數(shù)據(jù)庫(kù)(多個(gè))

    springboot如何連接兩個(gè)數(shù)據(jù)庫(kù)(多個(gè))

    這篇文章主要介紹了springboot如何連接兩個(gè)數(shù)據(jù)庫(kù)(多個(gè)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評(píng)論

普兰县| 邯郸市| 云梦县| 德格县| 苍山县| 桃园县| 富民县| 湖口县| 岐山县| 临桂县| 二连浩特市| 剑河县| 樟树市| 万盛区| 芷江| 安陆市| 曲松县| 乌拉特前旗| 水城县| 襄汾县| 临清市| 大冶市| 江川县| 乌恰县| 密云县| 洪洞县| 合川市| 衡东县| 双牌县| 沅陵县| 唐河县| 新宁县| 黔江区| 云梦县| 上栗县| 南汇区| 沈阳市| 朝阳区| 息烽县| 固始县| 凉城县|