MapStruct的一些常规用法

每天坚持写一篇原创文章。

使用过MapStruct之后,再也没用过BeanCopy来复制对象了。确实是非常好用的工具库。

MapStruct是一个代码生成器,简化了不同的Java Bean之间映射的处理,所以映射指的就是从一个实体变化成一个实体。例如我们在实际开发中,DAO层的实体和一些数据传输对象(DTO),大部分属性都是相同的,只有少部分的不同,通过mapStruct,可以让不同实体之间的转换变的简单。我们只需要按照约定的方式进行配置即可。

大家的命名都不一样,我个人是习惯把数据库的DO对象叫Entity实体。

返回前端的叫VO。

把Entity复制到VO并做一些操作或者转换,再返回前端,都会用到。

安装

1、引用

唯一需要注意的就是如果配合Lombok,需要在编译源码的插件上做好配置。

复制代码
<properties>
        <mapstruct.version>1.3.0.Final</mapstruct.version>
</properties>

<!-- MapStruct核心,包含了一些必要的注解-->
<dependencies>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${mapstruct.version}</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler-plugin.version}</version>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <compilerVersion>${java.version}</compilerVersion>
                <fork>true</fork>
                <encoding>${project.build.sourceEncoding}</encoding>
                <verbose>true</verbose>
                <annotationProcessorPaths>
                    <!-- 同时用Lombok,需要将Lombok放前面 -->
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>${lombok.version}</version>
                    </path>
                    <!-- MapStruct编译,注解处理器,根据注解自动生成Mapper的实现 -->
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>
                        <version>${mapstruct.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

2、定义转换接口

复制代码
@Mapper
public interface OrderConvertor {

    OrderConvertor INSTANCE = Mappers.getMapper(OrderConvertor.class);
 
    @Mapping(source = "student.birthday", target = "birthday", dateFormat = "yyyy-MM-dd HH:mm:ss") // 指定时间格式
    @Mapping(target = "name", source = "student.name", defaultValue = "张三") //默认值
    OrderVo toVo(OrderEntity order);
}

target表示目标属性名,source表示源属性名,一般在目标属性和源属性不同时使用,相同的属性名会自动进行映射。

MapStruct会自动生成对应接口的实现,并自动完成属性映射关系,List会自动进行批量处理。

3、使用时

复制代码
@Service
public class OrderService {
    public List<OrderVo> getOrderList() {
        // 获取数据库数据
        List<OrderEntity> result = selectOrderList();
        // 参数转换
        return OrderConvertor.INSTANCE.toVo(result);
    }
}

下面是我常用的一些功能记录

1、添加为Spring的Component组件

复制代码
@Mapper(componentModel = "spring")

2、List转换为String

类注解加上引用

复制代码
@Mapper(imports = {Collectors.class, TelegramGroupEntity.class})

代码里面:使用表达式,转换为字符串

复制代码
@Mapping(target = "groupStr", expression = "java(source.getBindGroups()!= null? source.getBindGroups().stream().map(TelegramGroupEntity::getName).collect(Collectors.joining(\", \")) : null)")
AcceptanceBankVo convert(AcceptanceBankEntity source);

直接转换List为换行的String

复制代码
@Mapping(target = "groupStr", expression = "java(source.getBindGroups()!= null? source.getBindGroups().stream().map(TelegramGroupEntity::getName).collect(Collectors.joining(\"\\n\")) : null)")

直接调用方法

复制代码
@Mapper(imports = {Collectors.class, TelegramGroupEntity.class, IndiaDateUtil.class})
public interface TransferBankConvert {
TransferBankConvert INSTANCE = Mappers.getMapper(TransferBankConvert.class);

@Mapping(target = "timeAgo", expression = "java(source.getLastActiveTime()!= null? IndiaDateUtil.getTimeAgo(source.getLastActiveTime(),\"Asia/Kolkata\") : null)")
TransferBankVo convert(TransferBankEntity source);
}

3、获取时间

复制代码
@Mapping(target = "recordTime",expression = "java(new java.util.Date())")

4、空检查

复制代码
@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)

5、枚举映射String和string到枚举

int转枚举的value

复制代码
@Mapper(imports = {AccptanceRoleTypeEnum.class}) // 加到类上引用进来

@Mapping(target = "roleText", expression = "java(AccptanceRoleTypeEnum.getItemValue(source.getRole()))")

枚举上加上:

复制代码
/**
 * 根据Value取描述
 * @param value
 * @return
 */
public static String getItemValue(Integer value) {
    AccptanceRoleTypeEnum match = Stream.of(values()).filter(item -> item.value.equals(value)).findAny().orElse(null);
    return match == null ? null : match.getDesc();
}

6、Fill同对象填充新对象,把source填充到target里面,和以前的beancopy一样的。

复制代码
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE,
        nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
@Mappings({
        @Mapping(target = "id", ignore = true),
        @Mapping(target = "createTime", ignore = true),
        @Mapping(target = "updateTime", ignore = true)
})
void fill(TelegramGroupRoleEntity source, @MappingTarget TelegramGroupRoleEntity target);

要忽略空值填充

复制代码
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
void update(DTO dto, @MappingTarget Bean bean);

7、Map提取,还是用表达式最简单

复制代码
@Mappings({
        @Mapping(expression = "java(mapConfig.getOrDefault(\"INPAY_RATES\",""))", target = "inpayRates"),
        @Mapping(expression = "java(mapConfig.getOrDefault(\"AUTO_CREDIT\",""))", target = "autoCredit")
})
TelegramGroupWithConfigVo convert(TelegramGroupEntity entity);

8、空值判断

复制代码
@Mapping(target = "targetField", expression = "java( sourceField == null || sourceField.isEmpty() ? null : sourceField )") 来将空字符串映射为 null

更多内容请关注我的公众号:青塬科技。

相关推荐
徐徐同学3 小时前
cpolar为IT-Tools 解锁公网访问,远程开发再也不卡壳
java·开发语言·分布式
Mr.朱鹏4 小时前
Nginx路由转发案例实战
java·运维·spring boot·nginx·spring·intellij-idea·jetty
白露与泡影6 小时前
2026版Java架构师面试题及答案整理汇总
java·开发语言
历程里程碑6 小时前
滑动窗口---- 无重复字符的最长子串
java·数据结构·c++·python·算法·leetcode·django
qq_229058016 小时前
docker中检测进程的内存使用量
java·docker·容器
我真的是大笨蛋6 小时前
InnoDB行级锁解析
java·数据库·sql·mysql·性能优化·数据库开发
钦拆大仁7 小时前
Java设计模式-单例模式
java·单例模式·设计模式
小手cool7 小时前
在保持数组中对应元素(包括负数和正数)各自组内顺序不变的情况下,交换数组中对应的负数和正数元素
java
笨手笨脚の7 小时前
深入理解 Java 虚拟机-04 垃圾收集器
java·jvm·垃圾收集器·垃圾回收
skywalker_117 小时前
Java中异常
java·开发语言·异常