mapstruct的spring拓展

简介: mapstruct的spring拓展

活着不一定要鲜艳,但一定要有自己的颜色。——张曙光

首先按照惯例放官网:

https://mapstruct.org/documentation/spring-extensions/reference/html/

基本的使用方式之前博客已经写过了我们就不再细表,这里简单放上链接

https://VampireAchao.gitee.io/2022/03/23/mapstruct/

在此之前还要配置对应的依赖和插件

<properties>
       <java.version>1.8</java.version>
       <!-- 编译生成代码插件版本号开始(避免mapstruct和lombok冲突,因此此处指定一个兼容的版本) -->
       <lombok.version>1.18.10</lombok.version>
       <mapstruct.version>1.3.0.Final</mapstruct.version>
       <mapstruct.spring.version>0.1.1</mapstruct.spring.version>
       <!-- 编译生成代码插件版本号结束 -->
   </properties>
<dependencies>
       <!-- 用到的GAV -->
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <version>${lombok.version}</version>
           <scope>provided</scope>
           <optional>true</optional>
       </dependency>
       <dependency>
           <groupId>org.mapstruct</groupId>
           <artifactId>mapstruct</artifactId>
           <version>${mapstruct.version}</version>
       </dependency>
       <dependency>
           <groupId>org.mapstruct.extensions.spring</groupId>
           <artifactId>mapstruct-spring-annotations</artifactId>
           <version>${mapstruct.spring.version}</version>
       </dependency>
   </dependencies>
<build>
       <plugins>
           <!-- 需要配置的插件 -->
    <plugin>
               <groupId>org.apache.maven.plugins</groupId>
               <artifactId>maven-compiler-plugin</artifactId>
               <version>3.8.1</version>
               <configuration>
                   <source>1.8</source>
                   <target>1.8</target>
                   <encoding>UTF-8</encoding>
                   <!-- lombok和mapstruct配置开始 -->
                   <annotationProcessorPaths>
                       <path>
                           <groupId>org.projectlombok</groupId>
                           <artifactId>lombok</artifactId>
                           <version>${lombok.version}</version>
                       </path>
                       <path>
                           <groupId>org.mapstruct</groupId>
                           <artifactId>mapstruct-processor</artifactId>
                           <version>${mapstruct.version}</version>
                       </path>
                       <path>
                           <groupId>org.mapstruct.extensions.spring</groupId>
                           <artifactId>mapstruct-spring-extensions</artifactId>
                           <version>${mapstruct.spring.version}</version>
                       </path>
                   </annotationProcessorPaths>
                   <!-- lombok和mapstruct配置结束 -->
               </configuration>
           </plugin>
       </plugins>
</build>


为什么要用?

因为我们之前使用中,需要对每个Mapper定义方法,然后调用对应的方法

如果对于简单的转换,能有一种能统一的规范,那样就不会乱

因此我们使用springConvert接口

完整类名为org.springframework.core.convert.converter.Converter

我们写法如下:

package com.ruben.simplescaffold.mapper.mapstruct;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.springframework.core.convert.converter.Converter;
import com.ruben.simplescaffold.entity.UserDetail;
import com.ruben.simplescaffold.pojo.vo.UserVO;
/**
 * 用户mapstruct转换mapper
 *
 * @author <achao1441470436@gmail.com>
 * @since 2022/3/23 19:18
 */
@Mapper(componentModel = "spring")
public interface MapUserMapper extends Converter<UserDetail, UserVO> {
    /**
     * po转vo
     *
     * @param userDetail po
     * @return vo
     */
    @Override
    @Mapping(source = "username", target = "uname")
    @Mapping(source = "password", target = "pwd")
    UserVO convert(UserDetail userDetail);
}

然后如果你按照官方文档接着使用:

package com.ruben.simplescaffold;
import javax.annotation.Resource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.convert.ConversionService;
import com.ruben.simplescaffold.entity.UserDetail;
import com.ruben.simplescaffold.pojo.vo.UserVO;
/**
 * @author <achao1441470436@gmail.com>
 * @since 2022/3/23 19:22
 */
@SpringBootTest
class MapUserMapperTest {
    @Resource
    private ConversionService conversionService;
    @Test
    void convertPoToVoTest() {
        UserVO userVO = conversionService.convert(UserDetail.builder().username("ruben").password("vampire").build(), UserVO.class);
        Assertions.assertEquals("ruben", userVO.getUname());
        Assertions.assertEquals("vampire", userVO.getPwd());
    }
}

你会发现踩坑了

报错:

org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [com.ruben.simplescaffold.entity.UserDetail] to type [com.ruben.simplescaffold.pojo.vo.UserVO]

然后我通过debug发现是没有将转换器添加进ConversionService

因此我们只要编写一个Config添加进去即可

package com.ruben.simplescaffold.config;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.GenericConversionService;
/**
 * 转换配置
 *
 * @author <achao1441470436@gmail.com>
 * @since 2022/5/1 0:44
 */
@Configuration
public class ConvertConfig {
    /**
     * 注册我们自定义的转换器
     *
     * @param converters        转换器列表
     * @param conversionService 转换服务
     * @param <T>               转换源泛型
     * @param <R>               转换目标泛型
     */
    public <T, R> ConvertConfig(List<Converter<T, R>> converters, GenericConversionService conversionService) {
        converters.forEach(conversionService::addConverter);
    }
}

再次使用

成功!

相关文章
|
Java Spring 容器
Spring中的自定义拓展点
Spring中的自定义拓展点
306 0
|
设计模式 Java Spring
Spring5深入浅出篇:Spring工厂设计模式拓展应用
Spring5深入浅出篇:Spring工厂设计模式拓展应用
|
Java 测试技术 Spring
(八)Spring Boot中对Logback的拓展
目录 一、Logback扩展点介绍 1、为什么不能用logback.xml配置文件呢? 2、扩展点缺点 二、指定Profile配置 三、环境属性
|
XML 人工智能 Java
Spring 5 中文解析核心篇-IoC容器之BeanDefinition继承与容器拓展点
Spring 5 中文解析核心篇-IoC容器之BeanDefinition继承与容器拓展点
409 0
|
XML Java 数据格式
SpringFramework核心技术一(IOC:Spring容器的拓展点)
Spring容器的拓展点 通常,应用程序开发人员不需要ApplicationContext 实现类的子类。相反,Spring IoC容器可以通过插入特殊集成接口的实现来扩展。
1332 0
|
9月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
1295 0
|
10月前
|
人工智能 Java 测试技术
Spring Boot 集成 JUnit 单元测试
本文介绍了在Spring Boot中使用JUnit 5进行单元测试的常用方法与技巧,包括添加依赖、编写测试类、使用@SpringBootTest参数、自动装配测试模块(如JSON、MVC、WebFlux、JDBC等),以及@MockBean和@SpyBean的应用。内容实用,适合Java开发者参考学习。
1100 0
|
6月前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
545 4
|
6月前
|
Java 测试技术 数据库连接
【SpringBoot(四)】还不懂文件上传?JUnit使用?本文带你了解SpringBoot的文件上传、异常处理、组件注入等知识!并且带你领悟JUnit单元测试的使用!
Spring专栏第四章,本文带你上手 SpringBoot 的文件上传、异常处理、组件注入等功能 并且为你演示Junit5的基础上手体验
1068 3
|
前端开发 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 介绍
本课介绍Spring Boot集成Thymeleaf模板引擎。Thymeleaf是一款现代服务器端Java模板引擎,支持Web和独立环境,可实现自然模板开发,便于团队协作。与传统JSP不同,Thymeleaf模板可以直接在浏览器中打开,方便前端人员查看静态原型。通过在HTML标签中添加扩展属性(如`th:text`),Thymeleaf能够在服务运行时动态替换内容,展示数据库中的数据,同时兼容静态页面展示,为开发带来灵活性和便利性。
506 0