You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不使用Setter,能否通过MapStruct实现@MappingTarget的相同效果?

无需Setter实现@MappingTarget类似效果的几种方案

针对你不想给实体类添加Setter,又要实现DTO到现有实体的字段更新需求,以下是几种可行方案:

方案1:MapStruct 直接字段访问(推荐)

MapStruct支持直接操作实体类的私有字段,无需依赖Setter方法。只需在Mapper接口中配置相关参数,框架会自动生成反射访问字段的代码。

代码示例

定义Mapper接口:

import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.ReportingPolicy;

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface AdConfigMapper {
    void updateEntity(AdConfigDto.UpdateDto updateDto, @MappingTarget AdConfigEntity adConfig);
}

原理说明

MapStruct生成的实现类会通过反射直接对实体类的私有字段进行赋值,完全不需要Setter方法,既保留了实体类的封装性,又实现了自动映射更新。

方案2:手动字段赋值(完全可控)

如果不想依赖框架,手动编写字段赋值逻辑是最直接的方式,可按需控制更新规则。

同包场景下的直接赋值

若业务方法与实体类处于同一包下,可直接访问包级私有字段(若实体类字段未加private修饰):

public void updateEntity(AdConfigDto.UpdateDto updateDto, AdConfigEntity adConfig) {
    adConfig.adType = updateDto.getAdType();
    adConfig.adCategory = updateDto.getAdCategory();
}

跨包场景下的反射赋值

若实体类字段为私有且跨包,可通过反射绕过访问限制:

import java.lang.reflect.Field;

public void updateEntity(AdConfigDto.UpdateDto updateDto, AdConfigEntity adConfig) {
    try {
        Field adTypeField = AdConfigEntity.class.getDeclaredField("adType");
        adTypeField.setAccessible(true);
        adTypeField.set(adConfig, updateDto.getAdType());

        Field adCategoryField = AdConfigEntity.class.getDeclaredField("adCategory");
        adCategoryField.setAccessible(true);
        adCategoryField.set(adConfig, updateDto.getAdCategory());
    } catch (NoSuchFieldException | IllegalAccessException e) {
        throw new RuntimeException("更新实体字段失败", e);
    }
}

方案3:Builder模式配合MapStruct

给实体类添加Builder支持,MapStruct可利用Builder完成实体更新,无需Setter。

修改实体类添加Builder

使用Lombok的@Builder(toBuilder = true)生成支持从现有实体创建Builder的代码:

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import javax.persistence.*;

@Entity(name = "ad_config")
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
public class AdConfigEntity extends BaseEntity {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private int adBannerId;
   private String adBannerTitle;
   private String adType;
   private String adCategory;
}

配置MapStruct使用Builder

import org.mapstruct.Builder;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;

@Mapper(componentModel = "spring", builder = @Builder(disableBuilder = false))
public interface AdConfigMapper {
    AdConfigEntity updateEntity(AdConfigDto.UpdateDto updateDto, @MappingTarget AdConfigEntity adConfig);
}

原理说明

MapStruct会调用实体的toBuilder()方法创建Builder,替换DTO中的字段后构建出新的实体对象,实现更新效果。


内容的提问来源于stack exchange,提问作者남혁준

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:45:27