mapstruct 实体类对应

该代码段展示了从ProjectZbfxgzExcel列表转换为ProjectZbfxgz列表的过程,使用Mapper进行实体类之间的映射。在保存数据时,获取登录用户的ID,设置添加时间和Xmid,然后将数据插入数据库。如果出现异常,日志会捕获并记录。
//    @Mapping(source = "sourceName", target = "targetName")
ProjectZbfxgz toTarget(ProjectZbfxgzExcel source); //后边转为前边
    List<ProjectZbfxgz> toTargetlist(List<ProjectZbfxgzExcel> source); list的后边转为前边
  /**
     * 实体类转换
     */
    private static ProjectZbfxgzExcelMapper INSTANCE = Mappers.getMapper(ProjectZbfxgzExcelMapper.class);




    private Boolean save() {
    //实体类的转换
        List<ProjectZbfxgz> projectZbfxgzs = INSTANCE.toTargetlist(cachedDataList);
        try {
            for (ProjectZbfxgz data : projectZbfxgzs) {
                LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
                data.setAddUser(loginUser.getUser().getUserId());
                data.setAddTime(DateUtils.getTime());
                data.setXmid(xmid);
                projectZbfxgzService.insertProjectZbfxgz(data);
            }
        } catch (Exception e) {
            log.info("数据插入异常!");
            return false;
        }
        return true;
    }


<think>我们正在讨论MapStruct如何忽略实体类中的公共方法。在MapStruct中,映射器接口会自动尝试映射源对象和目标对象中名称匹配的属性。但是,如果源对象中有一些公共方法(这些方法并不是我们想要映射的属性对应的getter),MapStruct可能会尝试调用这些方法,从而导致错误或不希望的映射。 解决方案: 1. 使用@Mapping注解忽略特定字段:我们可以通过在映射器接口的方法上使用@Mapping注解,并设置ignore=true来忽略特定的属性。 2. 使用@Mapper注解的unmappedTargetPolicy属性:设置未映射目标属性的策略,比如忽略。 3. 使用@BeanMapping(ignoreByDefault = true):然后显式指定需要映射的字段。 但是,这里的问题是如何忽略实体里面的公共方法?注意,MapStruct是通过getter和setter方法来访问属性的(如果它们存在的话)。因此,如果实体类中有一些公共方法,它们不是标准的getter(即不是以get或is开头的方法),那么MapStruct通常不会将它们视为属性的访问器。但是,如果这些公共方法是标准的getter(即方法名以get或is开头,并且没有参数),那么MapStruct会认为它们是属性的访问器,并尝试进行映射。 因此,我们可能遇到的问题是:实体类中有一些公共的getter方法,但是我们不希望MapStruct使用它们。那么我们可以通过以下方式忽略: 方法一:在映射器接口中,使用@Mapping注解忽略特定的属性(属性名就是方法名去掉get并首字母小写后的结果)。 例如,假设源对象有一个方法:`public String getFullName()`,但我们不想映射它。在目标对象中也有一个名为fullName的属性。我们可以: ```java @Mapper public interface MyMapper { @Mapping(target = "fullName", ignore = true) TargetObject toTarget(SourceObject source); } ``` 方法二:使用@BeanMapping(ignoreByDefault = true)来忽略所有字段,然后显式指定需要映射的字段。 ```java @Mapper public interface MyMapper { @BeanMapping(ignoreByDefault = true) @Mapping(source = "id", target = "id") @Mapping(source = "name", target = "name") // 只显式指定需要映射的字段,其他的都会被忽略 TargetObject toTarget(SourceObject source); } ``` 方法三:如果我们的公共方法并不是标准的getter(即不是以get或is开头),那么MapStruct默认是不会识别它们的,所以不需要特别处理。 另外,我们还可以通过配置MapStruct的访问策略来改变它查找访问器的方式。在@Mapper注解中,我们可以配置`componentModel`,但更相关的是我们可以通过`@MapperConfig`来配置一些全局的行为。不过,默认情况下MapStruct使用的是通过getter/setter来访问。 总结:要忽略实体中的公共方法,主要是要识别这些公共方法是否会被MapStruct误认为是getter。如果是,则需要在映射器中明确忽略这些属性。 根据引用[4]中提到的@Mapping注解的使用,我们可以通过指定source和target并设置ignore=true来忽略特定字段。 注意:MapStruct在映射时会自动忽略与目标属性不匹配的源属性(除非我们配置了不同的策略)。但是,如果源和目标有同名的属性(或通过名字匹配),而我们想忽略,那么就需要显式忽略。 因此,针对问题“MapStruct如何忽略实体里面的公共方法”,解决方案就是通过@Mapping注解显式忽略那些由公共getter方法生成的属性。 示例:假设Source类中有一个方法`public String getExtraInfo()`,而Target类中有一个属性`extraInfo`,但我们不想映射它。那么在映射器接口中: ```java @Mapper public interface MyMapper { @Mapping(target = "extraInfo", ignore = true) Target toTarget(Source source); } ``` 这样,MapStruct在生成映射代码时,就不会去调用Source的getExtraInfo()方法,也不会设置Target的extraInfo属性。 如果有很多需要忽略的字段,也可以考虑使用@BeanMapping(ignoreByDefault=true)然后只启用需要的映射。 另外,引用[1]提到MapStruct是通过普通的getter/setter调用来进行赋值的,所以控制哪些getter被调用就可以通过控制哪些属性被映射来实现。 因此,忽略实体里面的公共方法(指那些我们不想被映射的getter方法)的关键就是忽略它们对应的属性。 </think> ### MapStruct 忽略实体类公共方法的解决方案 在 MapStruct 映射过程中,有时需要忽略实体类中的公共方法(如工具方法、业务逻辑方法等),避免被误识别为属性映射方法。以下是三种解决方案: #### 1. 使用 `@BeanMapping(ignoreByDefault = true)` 显式忽略(推荐) ```java @Mapper public interface UserMapper { @BeanMapping(ignoreByDefault = true) // 先忽略所有映射 @Mapping(source = "id", target = "userId") @Mapping(source = "name", target = "username") UserDto toDto(User user); } ``` - **原理**:`ignoreByDefault=true` 关闭自动映射,仅保留显式声明的映射 - **效果**:忽略所有未显式指定的方法(包括公共方法) - **适用场景**:需要精确控制映射字段时[^4] #### 2. 通过 `@Mapping` 注解显式忽略特定方法 ```java @Mapper public interface UserMapper { @Mapping(target = "calculateAge", ignore = true) // 忽略特定方法 @Mapping(target = "formatBirthday", ignore = true) UserDto toDto(User user); } ``` - **原理**:`@Mapping(target = "methodName", ignore=true)` 明确忽略指定方法 - **效果**:精准排除不参与映射的方法 - **适用场景**:只需忽略少量特定方法时 #### 3. 配置全局忽略策略(MapStruct 1.5+) ```java @MapperConfig( unmappedTargetPolicy = ReportingPolicy.IGNORE // 全局忽略未映射目标 ) public interface GlobalMapperConfig {} @Mapper(config = GlobalMapperConfig.class) public interface UserMapper { UserDto toDto(User user); // 自动忽略非常规方法 } ``` - **原理**:`unmappedTargetPolicy = IGNORE` 全局忽略未匹配的目标属性 - **效果**:自动过滤非标准 getter 的公共方法 - **适用场景**:需要统一处理多个映射器时[^1] #### 最佳实践建议 1. **区分方法类型**: - 标准 getter(`getXxx()`)会被自动映射 - 非 getter 公共方法需显式忽略 ```java public class User { // 会被自动映射的属性 private Long id; public Long getId() { return id; } // ✅ 标准getter // 需要忽略的公共方法 public int calculateAge() { ... } // ❌ 需要显式忽略 } ``` 2. **使用 DTO 隔离**: - 创建纯净 DTO 类,仅包含需要的属性 - 避免实体类暴露业务方法(推荐领域驱动设计) ```java // 纯净DTO示例 public record UserDto(Long userId, String username) {} ``` 3. **验证映射结果**: ```java // 测试用例验证忽略效果 @Test void shouldIgnorePublicMethods() { User user = new User(1L, "Alice"); UserDto dto = UserMapper.INSTANCE.toDto(user); assertThat(dto).hasFieldOrProperty("userId"); assertThat(dto).hasNoNullFieldsOrProperties(); // 确保无意外映射 } ``` > **原理说明**:MapStruct 默认通过**方法名匹配**识别属性(如 `getXxx()` 对应属性 `xxx`)。非标准命名的公共方法可能被误识别为属性访问器。通过上述配置可精确控制映射范围。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值