为什么要使用MapStruct而不是BeanUtils.copyProperties?

为什么要使用MapStruct而不是BeanUtils.copyProperties?

为什么要使用MapStruct而不是BeanUtils.copyProperties?

本人在一家小公司刚实习的时候,还是保留了之前在网上学习项目时候的习惯,例如数据库实体类和VO类的属性赋值,还是使用了BeanUtils.copyProperties,每次我写完一个接口,公司那位带我的大佬就会帮我纠正一些不好的习惯或者是提醒我怎么优化,让我改用MapStruct替代BeanUtils.copyProperties,既然要替换,那肯定就要思考替换的理由了。

BeanUtils.copyProperties的使用方法很简单,下面便不会做示例了。

BeanUtils 和 MapStruct对比

性能上:MapStruct 比 BeanUtils更快,BeanUtils 他是采用反射的机制动态去进行拷贝映射,而MapStruct采用的是单纯的 get 和 set 方法。

便利性上:BeanUtils确实更快,因为用法很简单,而MapStruct的用法相对麻烦一点,需要编写新的接口和对应映射方法(不用实现),但是,MapStruct还支持多数据源,也就是使用多个Vo的属性拿来映射

下面主要介绍MapStruct用法,BeanUtils那个很简单下面便不会做示例了。

MapStruct 用法

依赖准备

        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.4.2.Final</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>1.4.2.Final</version>
            <scope>compile</scope>
        </dependency>

接口准备

准备一个convertor包,然后新建一个Convertor类

/**
 * @author liangry
 * @create 2022/9/23 9:13
 * spring注入方式
 */
@Mapper(componentModel = "spring")
public interface StudentConvertor {

    /**
     * 普通转换,字段名对应就会相应的赋值,如果Student没有ClassName字段,则即使Vo有,也不会有什么问题
     * @param studentVo
     * @return
     */
    Student fromStudentVo(StudentVo studentVo);

    /**
     * 自定义映射转换(多数据源),有时候可能原始类和目标类的某些字段名可能不相同,进行一个指定映射
     * @param userVo     用户名字赋值给学生名字
     * @param teacherVo  教师工号赋值给学生学号(只是为了方便假设)
     * @return
     */
    @Mappings({
            @Mapping(source = "userVo.name",target = "name"),
            @Mapping(source = "teacherVo.tno",target = "sno")
    })
    Student fromTeacherVoAndUserVo(UserVo userVo, TeacherVo teacherVo);

    /**
     * List 映射
     * @param studentVoList
     * @return
     */
    List<Student> fromStudentVoList(List<StudentVo> studentVoList);

}

在Controller接口模拟

	/**
     * 模拟多数据源和List映射,至于单数据源,读者应该能够看得懂,根据接口直接调用方法传参
     */
    @ApiOperation("testMapStruct")
    @GetMapping("/testMapStruct")
    public void testMapStruct() {

        UserVo userVo = new UserVo();
        userVo.setName("李白");

        TeacherVo teacherVo = new TeacherVo();
        teacherVo.setTno("1183010");

        Student student = studentConvertor.fromTeacherVoAndUserVo(userVo, teacherVo);

        System.out.println("查看情况多数据源映射情况" + student.toString());

        //=======下面是list映射=======

        List<StudentVo> studentVos = new ArrayList<>();

        //链式编程,在StudentVo类上面加上 @Accessors(chain = true) 注解即可
        studentVos.add(new StudentVo().setName("张三").setAge(18).setClassId(110L));
        studentVos.add(new StudentVo().setName("李四").setAge(18).setClassId(110L));
        studentVos.add(new StudentVo().setName("王五").setAge(18).setClassId(110L));

        List<Student> students = studentConvertor.fromStudentVoList(studentVos);

        //输出查看情况
        students.forEach(System.out::println);
    }

补充

还有一些别的功能,后面再找时间补充,比如说类型映射、逆映射、自定义映射方法使用其他值、使用表达式映射赋值。

参考文章:https://blog.youkuaiyun.com/qq_44732146/article/details/119968376

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值