微服务架构MapStruct属性映射
package com.jingdianjichi.subject.application.convert; import com.jingdianjichi.subject.application.dto.SubjectCategoryDTO; import com.jingdianjichi.subject.domain.entiy.SubjectCategoryBO; import javax.annotation.Generated; @Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2024-07-02T23:58:56+0800", comments = "version: 1.4.2.Final, compiler: javac, environment: Java 1.8.0_371 (Oracle Corporation)" ) public class SubjectCategoryDTOConverterImpl implements SubjectCategoryDTOConverter { @Override public SubjectCategoryBO convertBoToCategory(SubjectCategoryDTO subjectCategoryDTO) { if ( subjectCategoryDTO == null ) { return null; } SubjectCategoryBO subjectCategoryBO = new SubjectCategoryBO(); subjectCategoryBO.setId( subjectCategoryDTO.getId() ); subjectCategoryBO.setCategoryName( subjectCategoryDTO.getCategoryName() ); subjectCategoryBO.setCategoryType( subjectCategoryDTO.getCategoryType() ); subjectCategoryBO.setImageUrl( subjectCategoryDTO.getImageUrl() ); subjectCategoryBO.setParentId( subjectCategoryDTO.getParentId() ); subjectCategoryBO.setCount( subjectCategoryDTO.getCount() ); return subjectCategoryBO; } }
MapStruct是一个用于Java的代码生成库,主要用于简化对象到对象映射的代码编写工作。它的主要目标是减少在对象之间进行属性复制时所需的手动编码量,同时保持高性能和类型安全。
MapStruct的工作原理
MapStruct通过注解处理器(Annotation Processor)在编译时自动生成映射器(Mapper)的实现。(注意报错后刷新一下maven,推荐clean,install),否则自动生成类不会更新。当你在接口上应用@Mapper
注解后,MapStruct会自动分析接口中的映射方法,并在编译期间生成相应的实现类。这些生成的类可以高效地执行对象之间的字段映射,而无需在运行时进行反射,从而提高了性能。
使用MapStruct的基本步骤
-
定义映射接口: 在一个接口上添加
@Mapper
注解,该接口将包含映射方法的声明。Java1@Mapper 2public interface MyMapper { 3 // 定义映射方法 4 DestinationClass map(SourceClass source); 5}
-
实现映射方法: MapStruct会自动为接口中的映射方法生成实现。你可以选择使用默认的字段映射,也可以通过
@Mapping
注解指定更复杂的映射规则。Java1@Mapper 2public interface MyMapper { 3 @Mapping(source="sourceField", target="destinationField") 4 DestinationClass map(SourceClass source); 5}
-
使用映射器: 在应用程序中,可以通过依赖注入或直接实例化的方式使用映射器。
Java1MyMapper myMapper = ...; // 通过DI框架获取或直接实例化 2DestinationClass destination = myMapper.map(source);
MapStruct的特点
- 代码生成:MapStruct在编译时生成高效的映射器实现,避免了运行时的开销。
- 类型安全:由于映射器是在编译时生成的,因此可以确保类型安全,避免运行时错误。
- 灵活性:允许在映射过程中进行条件判断、数据转换和业务逻辑处理。
- 可扩展性:可以自定义映射器的行为,例如通过自定义注解或实现特定的映射策略。
- 集成性:与Spring和其他依赖注入框架有良好的集成,使得映射器的使用更加方便。
MapStruct的配置和集成
在Maven或Gradle项目中,你需要添加MapStruct的依赖以及相应的编译插件或注解处理器。例如,在Maven的pom.xml
中,你可能需要添加以下依赖和插件:
Xml
1<dependencies>
2 <dependency>
3 <groupId>org.mapstruct</groupId>
4 <artifactId>mapstruct</artifactId>
5 <version>最新版本号</version>
6 </dependency>
7</dependencies>
8
9<build>
10 <plugins>
11 <plugin>
12 <groupId>org.apache.maven.plugins</groupId>
13 <artifactId>maven-compiler-plugin</artifactId>
14 <version>最新版本号</version>
15 <configuration>
16 <source>1.8</source>
17 <target>1.8</target>
18 </configuration>
19 </plugin>
20 <plugin>
21 <groupId>org.mapstruct</groupId>
22 <artifactId>mapstruct-maven-plugin</artifactId>
23 <version>最新版本号</version>
24 <executions>
25 <execution>
26 <goals>
27 <goal>process</goal>
28 </goals>
29 </execution>
30 </executions>
31 </plugin>
32 </plugins>
33</build>
在Gradle的build.gradle
文件中,配置类似,但使用的是不同的语法。
总之,MapStruct是一个强大的工具,它极大地简化了Java应用程序中对象映射的任务,同时提供了高度的定制性和性能。
一定要主要mapstruct方法自动生成的内容
转换语句每次转换均失败
SubjectCategoryBO subjectCategoryBO = SubjectCategoryDTOConverter.INSTANCE.convertBoToCategory(subjectCategoryDTO);
System.out.println("subjectCategoryBO1"+subjectCategoryBO);
System.out.println("subjectCategoryBO1"+subjectCategoryBO);
查询了确保subjectCategoryBO ,subjectCategoryDTO字段内容均一致,结果依旧转换失败,最后发现初次生成的缓存代码未更新,导致字段丢失。
重构maven成功解决。
转换代码如下:
controller层
@PostMapping ("/add") public Result<Boolean> add(@RequestBody SubjectCategoryDTO subjectCategoryDTO) { // 记录请求数据 log.debug("Received SubjectCategoryDTO: {}", subjectCategoryDTO); System.out.println(subjectCategoryDTO); // 参数校验 if (subjectCategoryDTO == null || StringUtils.isEmpty(subjectCategoryDTO.getCategoryName())) { return Result.fail(); } try { // 转换前记录原始数据 log.debug("Converting SubjectCategoryDTO to SubjectCategoryBO..."); if (subjectCategoryDTO!=null) { // 执行转换 SubjectCategoryBO subjectCategoryBO = SubjectCategoryDTOConverter.INSTANCE.convertBoToCategory(subjectCategoryDTO); System.out.println("subjectCategoryBO1"+subjectCategoryBO); // 转换后检查 if (subjectCategoryBO == null) { log.error("Conversion from DTO to BO failed."); return Result.fail(); }
converter类
package com.jingdianjichi.subject.application.convert; import com.jingdianjichi.subject.application.dto.SubjectCategoryDTO; import com.jingdianjichi.subject.domain.entiy.SubjectCategoryBO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; import com.jingdianjichi.subject.domain.service.SubjectCategoryDomainService; @Mapper public interface SubjectCategoryDTOConverter { SubjectCategoryDTOConverter INSTANCE = Mappers.getMapper(SubjectCategoryDTOConverter.class); SubjectCategoryBO convertBoToCategory(SubjectCategoryDTO subjectCategoryDTO); // List<SubjectCategoryBO> convertBoToCategory(List<SubjectCategory> categoryList); }
最后查看自动生成的缓存是否有问题
package com.jingdianjichi.subject.application.convert; import com.jingdianjichi.subject.application.dto.SubjectCategoryDTO; import com.jingdianjichi.subject.domain.entiy.SubjectCategoryBO; import javax.annotation.Generated; @Generated( value = "org.mapstruct.ap.MappingProcessor", date = "2024-07-02T23:58:56+0800", comments = "version: 1.4.2.Final, compiler: javac, environment: Java 1.8.0_371 (Oracle Corporation)" ) public class SubjectCategoryDTOConverterImpl implements SubjectCategoryDTOConverter { @Override public SubjectCategoryBO convertBoToCategory(SubjectCategoryDTO subjectCategoryDTO) { if ( subjectCategoryDTO == null ) { return null; } SubjectCategoryBO subjectCategoryBO = new SubjectCategoryBO(); subjectCategoryBO.setId( subjectCategoryDTO.getId() ); subjectCategoryBO.setCategoryName( subjectCategoryDTO.getCategoryName() ); subjectCategoryBO.setCategoryType( subjectCategoryDTO.getCategoryType() ); subjectCategoryBO.setImageUrl( subjectCategoryDTO.getImageUrl() ); subjectCategoryBO.setParentId( subjectCategoryDTO.getParentId() ); subjectCategoryBO.setCount( subjectCategoryDTO.getCount() ); return subjectCategoryBO; } }