- 昨天第一天去公司上班,刚起步的项目,自己这边的模块可能还没开始,第二天我就开始设计表了,虽说经验不足,但也不怕,只有尝试才能不断进步嘛,这不,看到一些不懂的代码,今天总算是搞明白了,其中的MapStruct就是一个,学到新东西总是让人忍不住的开心啊
开撸案例,边用边学 起步依赖在我们的分布式结构中,由controller直接到dao层的查询条件对象我们一般用co,由dao到service层的数据传输对象我们一般用dto作数据返回,而由controller到service我们一般用vo作为业务处理,其中数据库返回的entity中可能有不想暴露给前端的数据,这时我们就需要使用转换,移除也可以说是过滤到某些字段,在我们最快能联想到的就是使用set和get方法去实现转换的效果,但是这样代码不优雅且冗余,于是MapStruct应运而生!
所有依赖展示一下org.mapstruct mapstruct-jdk8 1.4.1.Final org.mapstruct mapstruct-processor 1.4.1.Final
原始entityorg.springframework.boot spring-boot-starter-web 2.5.4 org.springframework.boot spring-boot-starter-test mysql mysql-connector-java 5.1.47 com.alibaba druid-spring-boot-starter 1.1.23 org.projectlombok lombok 1.18.20 com.baomidou mybatis-plus-boot-starter 3.4.2 org.mapstruct mapstruct-jdk8 1.2.0.Final org.mapstruct mapstruct-processor 1.2.0.Final
@Data
@TableName("mall_goods")
public class MallGoodsEntity implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
private Long spuId;
private String productSn;
private String goodsName;
private Long defaultSkuId;
private String auditStatus;
private String isMarketable;
private Long brandId;
private String caption;
private Long category1Id;
private Long category2Id;
private Long category3Id;
private String albumPics;
private BigDecimal price;
private Long typeTemplateId;
private String isEnableSpec;
private String isDelete;
private String copyId;
private String spuSpecInfo;
private String hot;
private Integer sale;
private LocalDateTime createTime;
private LocalDateTime updateTime;
private String sellerId;
}
表信息如下
domain层的模型如下可以看到这里的表和entity的字段是一一对应的
@Data
public class MallGoodsVO {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
private Long spuId;
private String productSn;
private String goodsName;
private Long defaultSkuId;
private String auditStatus;
}
spring中的java配置类为了方便演示,我只截取了部分字段作为vo返回
@MapperConfig(
componentModel = "spring",
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
unmappedTargetPolicy = ReportingPolicy.WARN
)
@Configuration
public class MapStructConfiguration {
}
| 选项 | 目的 | 默认 |
|---|---|---|
| suppressGeneratorTimestamp | 如果设置为 true ,@Generated 则会在生成的映射器类的注释中创建时间戳 | false |
| suppressGeneratorVersionInfoComment | 如果设置为 true ,则会在生成的映射器类中注释中的 comment 属性创建 @Generated 被抑制。该注释包含有关 MapStruct版本和用于注释处理的编译器的信息 | false |
| defaultComponentModel | 根据生成映射器的组件模型的名称,支持的值 : 1> default : 映射器不使用组件模型,通常通过实例检索实例 Mappers#getMapper(Class) 2> cdi : 生成的映射器是一个应用程序范围的CDI bean,可以通过检索 @Inject 3> spring : 生成的映射器是一个单一范围的 Spring bean,可以通过检索 @Autowired 4> jsr330 : 生成的映射器使用 {@code @Named} 进行注释,并且可以通过 @Inject 使用 Spring 进行检索如果为特定的映射器通过组件模型 @Mapper#componentModel() ,则注释中的值优先 | default |
| unmappedTargetPolicy | 在映射方法的目标对象的属性未填充源值的情况下应用的默认报告策略,支持的值 : 1> ERROR : 任何未映射的目标属性都将导致映射代码生成失败 2> WARN : 任何未映射的目标属性将在构建时引发警告 3> IGNORE : 未映射的目标属性被忽略如果为特定的映射器通过了策略 @Mapper#unmappedTargetPolicy() ,则注释中的值优先 | WARN |
- mapper层
@Mapper public interface MallGoodsEntityMapper extends baseMapper{ }
- service层
@Service public class MallGoodsEntityServiceImpl extends ServiceImpl转换的接口implements MallGoodsEntityService { }
// 这里的mapper注解是mapstruct提供的
@Mapper(config = MapStructConfiguration.class)
public interface MallGoodsConvert {
MallGoodsVO toDto(MallGoodsEntity mallGoodsEntity);
}
controller层直接调用转换
@RestController
@RequestMapping("goods")
public class MallGoodsController {
@Autowired
private MallGoodsEntityService mallGoodsEntityService;
@Autowired
private MallGoodsConvert mallGoodsConvert;
@RequestMapping("list")
public MallGoodsVO list() {
return mallGoodsConvert.toDto(mallGoodsEntityService.getById(1));
}
}
运行调用后看结果
按原本的entity来看应该是很多字段的,而经过mapstruct之后只有VO中的字段了
- 反馈的数据
至此,我们MapStruct的基本使用完毕,学会了基本就要往更深处去研究了,加油!!!



