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

Java對(duì)象字段拷貝最佳實(shí)踐分享

 更新時(shí)間:2025年03月03日 08:29:15   作者:碼農(nóng)研究僧  
文章介紹了幾種常見的對(duì)象字段拷貝方法,包括手動(dòng)set、BeanUtils.copyProperties、Lombok的@Builder和MapStruct,每種方法都有其優(yōu)缺點(diǎn)和適用場(chǎng)景,推薦使用MapStruct,因?yàn)樗诰幾g期生成代碼,性能最優(yōu),支持復(fù)雜對(duì)象映射,需要的朋友可以參考下

前言

一開始在線表和歷史表都是一張表,只不過字段設(shè)置不一樣,顯示不一樣

但后續(xù)數(shù)據(jù)越來越多,為了不影響在線表,數(shù)據(jù)最終得落入歷史表,不影響在線表的CRUD

以下章節(jié)圍繞如何克隆在線表的數(shù)據(jù)

對(duì)象字段拷貝 的需求,比如從數(shù)據(jù)庫查詢出的對(duì)象需要轉(zhuǎn)換成 DTO,或者在審核流程中更新一張表的同時(shí)寫入歷史表等

如果手動(dòng) set 字段,代碼會(huì)變得繁瑣,難以維護(hù)

1. 傳統(tǒng)set(不推薦)

最簡(jiǎn)單的方法是 手動(dòng)賦值,但是當(dāng)字段較多時(shí),代碼冗長(zhǎng)且容易遺漏。

示例代碼:

CheckBoxDetailDO checkBoxDetailDO = new CheckBoxDetailDO();
checkBoxDetailDO.setCheckStatus(1L);
checkBoxDetailDO.setCntr(checkBox.getCntr());
checkBoxDetailDO.setImgCntrF(checkBox.getImgCntrF());
checkBoxDetailDO.setCreateTime(checkBox.getCreateTime());

缺點(diǎn):

  • 代碼冗長(zhǎng):如果 CheckBoxDO有幾十個(gè)字段,手寫 set 非常麻煩
  • 易出錯(cuò):如果 CheckBoxDO結(jié)構(gòu)變化,必須手動(dòng)修改所有 set 邏輯,維護(hù)成本高

適用場(chǎng)景:

字段較少(少于 3 個(gè)字段)

除了set,還有一種跟他很像,我也放在這個(gè)章節(jié)

Lombok 的 @Builder,可以使用 builder() 方法來 鏈?zhǔn)劫x值,提高可讀性(但我感覺沒啥差異)

CheckBoxDetailDO checkBoxDetailDO = CheckBoxDetailDO.builder()
        .checkStatus(1L)
        .cntr(checkBox.getCntr())
        .imgCntrF(checkBox.getImgCntrF())
        .createTime(checkBox.getCreateTime())
        .build();

2. copyProperties(有局限)

CheckBoxDetailDO checkBoxDetailDO = new CheckBoxDetailDO();
BeanUtils.copyProperties(checkBox, checkBoxDetailDO);
checkBoxDetailDO.setCheckStatus(1L); // 額外賦值

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

  • 代碼簡(jiǎn)潔,自動(dòng)拷貝 相同字段,避免手動(dòng) set
  • 無需額外依賴,Spring 內(nèi)置

缺點(diǎn):

  • 性能一般,使用了 反射,比手動(dòng) set 慢
  • 字段名必須完全匹配,如果 CheckBoxDetailDO 和 CheckBoxDO字段名不一樣,無法拷貝
  • 不支持復(fù)雜轉(zhuǎn)換,比如 數(shù)據(jù)類型不同(int vs String)、默認(rèn)值設(shè)置 等

適用場(chǎng)景:

  • 字段名和類型完全匹配的簡(jiǎn)單拷貝
  • 項(xiàng)目已經(jīng)使用 Spring,避免額外依賴

3. MapStruct(推薦)

如果 CheckBoxDO和 CheckBoxDetailDO 結(jié)構(gòu)類似,并且字段較多,推薦使用 MapStruct 進(jìn)行自動(dòng)對(duì)象映射
MapStruct 在編譯期生成代碼,相比 BeanUtils 性能更優(yōu),并且支持字段轉(zhuǎn)換

1、定義轉(zhuǎn)換接口

創(chuàng)建一個(gè) Mapper 接口,并用 @Mapper 注解標(biāo)識(shí)。

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

@Mapper(componentModel = "spring")
public interface CheckBoxConverter {
    CheckBoxConverter INSTANCE = Mappers.getMapper(CheckBoxConverter.class);

    @Mapping(target = "checkStatus", constant = "1L") // 強(qiáng)制設(shè)定 checkStatus 為 1
    CheckBoxDetailDO toDetailDO(CheckBoxDO checkBox);
}

2、調(diào)用轉(zhuǎn)換

@Resource
private ChekBoxDetailMapper chekBoxDetailMapper;

CheckBoxDetailDO checkBoxDetailDO = CheckBoxConverter.INSTANCE.toDetailDO(checkBox);
chekBoxDetailMapper.insert(checkBoxDetailDO);

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

  • 高性能,編譯期生成代碼,沒有反射開銷
  • 自動(dòng)映射字段,省去 set 代碼
  • 支持類型轉(zhuǎn)換,例如 String -> Long、Date -> LocalDateTime 等
  • 字段名不同也能映射,可以用 @Mapping(source = “oldField”, target = “newField”) 自定義映射關(guān)系

缺點(diǎn):

需要引入 MapStruct 依賴,但一次配置,終身受益

適用場(chǎng)景:

  • 字段較多且映射規(guī)則較復(fù)雜
  • 項(xiàng)目對(duì)性能要求較高(比 BeanUtils 更快)

但是會(huì)有bug:

后續(xù)發(fā)現(xiàn)id自增字段也被復(fù)刻了!

采取忽略的方式:

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

    @Mapping(target = "id", ignore = true) // 忽略 id 字段
    @Mapping(target = "checkStatus", constant = "1L") // 強(qiáng)制設(shè)定 checkStatus 為 1
    CheckBoxDetailDO toDetailDO(CheckBoxDO checkBox);
}

截圖如下:

這里拓展下這種方式其他的知識(shí)點(diǎn):

使用 @BeanMapping(ignoreByDefault = true)(僅拷貝指定字段)

類似如下代碼:

@Mapper(componentModel = "spring")
public interface CheckBoxConverter {
    CheckBoxConverter INSTANCE = Mappers.getMapper(CheckBoxConverter.class);

    @BeanMapping(ignoreByDefault = true)
    @Mapping(target = "cntr", source = "cntr")
    @Mapping(target = "imgCntrF", source = "imgCntrF")
    @Mapping(target = "createTime", source = "createTime")
    @Mapping(target = "checkStatus", constant = "1L")
    CheckBoxDetailDO toDetailDO(CheckBox checkBox);
}

如果不想修改代碼:

CheckBoxDetailDO checkBoxDetailDO = CheckBoxConverter.INSTANCE.toDetailDO(checkBox);
checkBoxDetailDO.setId(null); // 手動(dòng)清除 id

最后,不要忘記insert,否則它只是一個(gè)對(duì)象,沒有存儲(chǔ)

CheckBoxDetailDO checkBoxDetailDO = CheckBoxConverter.INSTANCE.toDetailDO(checkBox);
checkBoxDetailMapper.insert(checkBoxDetailDO); // 插入數(shù)據(jù)庫

4. 總結(jié)

方案代碼簡(jiǎn)潔度性能適用場(chǎng)景
手動(dòng) set? 差?
BeanUtils.copyProperties? 好?一般字段完全匹配,簡(jiǎn)單拷貝
Lombok @Builder? 好? 快代碼可讀性強(qiáng),構(gòu)建新對(duì)象
MapStruct? 最優(yōu)? 最優(yōu)復(fù)雜對(duì)象映射,性能高

以上就是Java對(duì)象字段拷貝最佳實(shí)踐分享的詳細(xì)內(nèi)容,更多關(guān)于Java對(duì)象字段拷貝的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • struts2實(shí)現(xiàn)多文件上傳

    struts2實(shí)現(xiàn)多文件上傳

    這篇文章主要為大家詳細(xì)介紹了struts2實(shí)現(xiàn)多文件上傳,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • spring的applicationContext.xml文件與NamespaceHandler解析

    spring的applicationContext.xml文件與NamespaceHandler解析

    這篇文章主要介紹了spring的applicationContext.xml文件與NamespaceHandler解析,Spring容器啟動(dòng),在創(chuàng)建BeanFactory時(shí),需要加載和解析當(dāng)前ApplicationContext對(duì)應(yīng)的配置文件applicationContext.xml,從而獲取bean相關(guān)的配置信息,需要的朋友可以參考下
    2023-12-12
  • java從字符串中提取數(shù)字的簡(jiǎn)單實(shí)例

    java從字符串中提取數(shù)字的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)硪黄猨ava從字符串中提取數(shù)字的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-10-10
  • 詳解Java線程-守護(hù)線程與用戶線程

    詳解Java線程-守護(hù)線程與用戶線程

    這篇文章主要介紹了Java守護(hù)線程與用戶線程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • SpringBoot日志框架之Log4j2快速入門與參數(shù)詳解

    SpringBoot日志框架之Log4j2快速入門與參數(shù)詳解

    本文介紹了SpringBoot日志框架log4j2的基本使用和配置方法,包括將日志輸出到控制臺(tái)、文件、Elasticsearch和Kafka,多個(gè)輸出目的地的配置,異步日志記錄器的使用以及l(fā)og4j2.xml配置文件的詳細(xì)語法和參數(shù)含義,需要的朋友可以參考下
    2023-05-05
  • springboot?aop里的@Pointcut()的配置方式

    springboot?aop里的@Pointcut()的配置方式

    這篇文章主要介紹了springboot?aop里的@Pointcut()的配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 深入了解Java File分隔符和Path分隔符的使用

    深入了解Java File分隔符和Path分隔符的使用

    不同的操作系統(tǒng)使用不同的字符作為文件和路徑分隔符。當(dāng)我們的應(yīng)用程序需要在多個(gè)平臺(tái)上運(yùn)行時(shí),我們需要正確處理這些問題。Java幫助我們選擇一個(gè)合適的分隔符,本文就來聊聊Java中File分隔符和 Path分隔符的使用
    2022-07-07
  • java使用nio2拷貝文件的示例

    java使用nio2拷貝文件的示例

    這篇文章主要介紹了java使用nio2拷貝文件的示例,需要的朋友可以參考下
    2014-04-04
  • 使用Java實(shí)現(xiàn)Excel轉(zhuǎn)PDF的示例詳解

    使用Java實(shí)現(xiàn)Excel轉(zhuǎn)PDF的示例詳解

    在實(shí)際的開發(fā)過程中,我們常常會(huì)遇到需要將 Excel 文件轉(zhuǎn)換為 PDF 文件的需求,本文為大家介紹一種Java中的常見實(shí)現(xiàn)方式,需要的可以參考一下
    2025-02-02
  • 解決MultipartFile.transferTo(dest) 報(bào)FileNotFoundExcep的問題

    解決MultipartFile.transferTo(dest) 報(bào)FileNotFoundExcep的問題

    這篇文章主要介紹了解決MultipartFile.transferTo(dest) 報(bào)FileNotFoundExcep的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評(píng)論