mapstruct使用及@Mapper(componentModel=“Spring“)

前言
之前在进行DTO、VO、与Entity 转换时,经常使用 BeanUtils.copyProperties();方法进行参数转换,或者手动写gettersetter方法。今天在看公司框架的时候发现了另外一种方法进行参数转换。这样进行转换更快速、安全。

与手动编写映射代码相比,MapStruct通过生成繁琐且易于出错的代码来节省时间。遵循配置方法上的约定,MapStruct使用合理的默认值,但在配置或实现特殊行为时不加理会。
与动态映射框架相比,MapStruct具有以下优点:

通过使用普通方法调用(settter/getter)而不是反射来快速执行
编译时类型安全性:只能映射相互映射的对象和属性,不能将order实体意外映射到customer DTO等。
如果有如下问题,编译时会抛出异常
3.1 映射不完整(并非所有目标属性都被映射)
3.2 映射不正确(找不到正确的映射方法或类型转换)
可以通过freemarker定制化开发
使用
1、引入
那么我们如何使用mapstruct呢,首先在pom文件中引入

<!-- mapstruct -->
<!--mapstruct核心 org.mapstruct:mapstruct:包含必需的注释,例如@Mapping-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.2.0.Final</version>
</dependency>
<!--mapstruct编译 org.mapstruct:mapstruct-processor:包含注释处理器,该注释处理器生成映射器实现-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.2.0.Final</version>
</dependency>
<!-- mapstruct end -->
Lombok依赖,用于生成类中的SetterGetter方法。不是必须引用

<dependency>
<groupid>org.projectlombok</groupid>
<artifactid>lombok</artifactid>

</dependency>
2、使用
这里我只实例简单的用法,如果想深入了解可以参考文章

http://t.csdn.cn/GjtZL
http://t.csdn.cn/GjtZL
引入完依赖后 我们定义一个接口类

//导mapstruct包下的
@Mapper(componentModel="spring")
@Component
public interface OrderInputConvert {

OrderInputConvert INATANCE = Mappers.getMapper(OrderInputConvert.class);

//意为 把input入参类 转换为 order名称的实体类
Order input2Do(OrderInput inputParam);

//同理 List集合的转换
List<Order> inputList2DoList(List<OrderInput> inputParamList);

}
至此 最基本的mapstruct 配置就完成了,使用时 把这个接口自动注入进到使用的类中,再通过方法名传入vo\input 等需要转换成实体类的参数即可使用。

那么他是如何实现的呢? 当编译完成后 在项目的 “target ” 包下找到同名类 我们会发现多生成了一个 impl实现类,让我们来看一看mapstruct 是如何实现的。

public class OrderacptInputConvertImpl implements OrderacptInputConvert {
public OrderacptInputConvertImpl() {
}
//普通的转换实现类
public Orderacpt input2Do(OrderacptInput inputParam) {
if (inputParam == null) {
return null;
} else {
Orderacpt orderacpt = new Orderacpt();
orderacpt.setId(inputParam.getId());
orderacpt.setTheOrder(inputParam.getTheOrder());
orderacpt.setAcptDate(inputParam.getAcptDate());
orderacpt.setAcptTime(inputParam.getAcptTime());
orderacpt.setTheDevice(inputParam.getTheDevice());
//...多余代码略 同样都是 setter操作
return orderacpt;
}
}
//List转换类
public List<Orderacpt> inputList2DoList(List<OrderacptInput> inputParamList) {
if (inputParamList == null) {
return null;
} else {
List<Orderacpt> list = new ArrayList(inputParamList.size());
Iterator var3 = inputParamList.iterator();

while(var3.hasNext()) {
OrderacptInput orderacptInput = (OrderacptInput)var3.next();
list.add(this.input2Do(orderacptInput));
}

return list;
}
}
}
通过这个实现类我们可以看到,原理是Setter操作,使用mapstruct后 可以更快速的进行参数的转换,使用BeanUtils也是可以的(但是我在使用BeanUtils时有遇到过一些bug 有的赋值是会出现bug 的 看咱们具体使用情况定)。

3、项目中使用
我们再看一下实际使用情况

//service层实现类 IOrderFacade 接口的实现类
public class OrderFacadeImpl implements IOrderFacade {

//使用@Autowired进行自动注入 ,注入刚刚上面咱们写好的 使用@Mapper(componentModel="spring")注解定义的convert接口
@Autowired
OrderInputConvert inputConvert;

@Autowired
OrderOutputConvert outputConvert;


@Override
public boolean updateById(OrderInput inputParam){
//直接传入input值即可转换完成
Order doObject = inputConvert.input2Do(inputParam);
return iOrderService.updateById(doObject);
}

}
基本的使用说明 就介绍到这里,如果想深入了解 可以继续查阅相关文档。
————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/qq_39535439/article/details/131167805

posted @ 2024-06-26 17:30  枫树湾河桥  阅读(391)  评论(0编辑  收藏  举报
Live2D