MapStruct基础使用

今天分享一个实习期间遇到的一个将entity实体类转化为dto展示类的Java实体映射工具。
MapStruct允许我们只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了复杂繁琐的映射实现。
MapStruct官网地址: http://mapstruct.org/
下面展示下这个工具类的基本功能:
1、创建一个springboot项目
第一步:通过Spring初始化器创建一个springboot项目
在这里插入图片描述
第二步:给工程命名和分组——>next:
在这里插入图片描述
第三步:我是为项目选择引入了web和lombok模块,你也可以按照自己的需求引入相应的木块模块构建项目——>next在这里插入图片描述
第四步:finish在这里插入图片描述
2、搭建基本的用于测试MapStruct项
(1)poem.xml中引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.chen</groupId>
    <artifactId>test</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>test</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
        <mybatisplus-spring-boot-starter.version>1.0.4</mybatisplus-spring-boot-starter.version>
        <mybatisplus.version>2.3.3</mybatisplus.version>
        <lombok.version>1.18.8</lombok.version>
        <hutool.version>4.6.17</hutool.version>
        <cxf.version>3.1.6</cxf.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
		<!-- MapStruct -->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-jdk8</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!--实例转换插件,激活Idea插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                    </annotationProcessorPaths>
                    <compilerArgs>
                        <compilerArg>
                            -Amapstruct.suppressGeneratorTimestamp=false
                        </compilerArg>
                        <compilerArg>
                            -Amapstruct.suppressGeneratorVersionInfoComment=false
                        </compilerArg>
                        <compilerArg>
                            -Amapstruct.defaultComponentModel=spring
                        </compilerArg>
                        <compilerArg>
                            -Amapstruct.unmappedTargetPolicy=IGNORE
                        </compilerArg>
                    </compilerArgs>
                    <compilerArguments>
                        <extdirs>src\main\webapp\WEB-INF\lib</extdirs>
                    </compilerArguments>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

(2)创建实体类和展示类
A、实体类

@Component
@Data
public class DeptCategory {
    //部门id
    private Integer id;
    //部门名称
    private String name;
    //部门编码
    private String code;
    //部门类别
    private Integer type;
}

B、展示类

@Data
public class DeptCategoryDTO {
    //部门id
    private Integer deptId;
    //部门名称
    private String deptName;
    //部门编码
    private String deptCode;
    //部门类别
    private Integer deptType;
}

C、MapStruct转化工具类

package com.chen.test.conver;
import com.chen.test.dto.DeptCategoryDTO;
import com.chen.test.entity.DeptCategory;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
@Mapper
public interface DeptCategoryConver extends BaseConver {
    //@Mapping(source = "id",target = "deptId")
    @Mappings({
        @Mapping(source = "id",target = "deptId"),
        @Mapping(source = "code",target = "deptCode")
    })
    DeptCategoryDTO entity2dto(DeptCategory deptCategory);
}

父类BaseConver也是个接口,当转化类比较多时可以用于抽取一些公共功能进行拓展(像时间串格式转化等)。

package com.chen.test.conver;
public interface BaseConver {
}

D、创建测试类

package com.chen.test;
import com.chen.test.conver.DeptCategoryConver;
import com.chen.test.dto.DeptCategoryDTO;
import com.chen.test.entity.DeptCategory;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class TestApplicationTests {
    @Autowired
    private DeptCategoryConver deptCategoryConver;
    @Autowired
    private DeptCategory deptCategory;
    @Test
    void testMapStruct() {
        deptCategory.setId(1);
        deptCategory.setCode("A1001");
        deptCategory.setName("后勤部");
        deptCategory.setType(2);
        DeptCategoryDTO deptCategoryDTO = deptCategoryConver.entity2dto(deptCategory);
        System.out.println(deptCategoryDTO);
    }
}

运行结果:在这里插入图片描述
很显然我们在代码编写时并没有对接口DeptCategoryConver做任何实现类,只是添加了@Mapper注解代码编译后便可以通过entity2dto()方法便可以进入到其实现类中:

package com.chen.test.conver;

import com.chen.test.dto.DeptCategoryDTO;
import com.chen.test.entity.DeptCategory;
import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-11-12T14:38:21+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_211 (Oracle Corporation)"
)
@Component
public class DeptCategoryConverImpl implements DeptCategoryConver {

    @Override
    public DeptCategoryDTO entity2dto(DeptCategory deptCategory) {
        if ( deptCategory == null ) {
            return null;
        }

        DeptCategoryDTO deptCategoryDTO = new DeptCategoryDTO();

        deptCategoryDTO.setDeptId( deptCategory.getId() );
        deptCategoryDTO.setDeptCode( deptCategory.getCode() );

        return deptCategoryDTO;
    }
}

很显然这个类并不是我们编码的而是MapStruct帮我们生成的。这个实现类位于:在这里插入图片描述
下面。

(3)多个entity对一个dto
创建一个Employee类:

@Component
@Data
public class Employee {
    //id
    private Integer id;
    //姓名
    private String name;
    //性别
    private String gender;
    //邮箱
    private String email;
}

对展示类添加属性:

@Data
public class DeptCategoryDTO {
    //部门id
    private Integer deptId;
    //部门名称
    private String deptName;
    //部门编码
    private String deptCode;
    //部门类别
    private Integer deptType;
    //员工id
    private Integer empId;
    //员工姓名
    private String empName;
    //员工性别
    private String empGender;
    //员工邮箱
    private String empEmail;
}

映射接口:

@Mapper
public interface DeptCategoryConver extends BaseConver {
    //@Mapping(source = "id",target = "deptId")
    @Mappings({
        @Mapping(source = "dept.id",target = "deptId"),
            @Mapping(source = "dept.code",target = "deptCode"),
            @Mapping(source = "dept.name",target = "deptName"),
            @Mapping(source = "emp.id",target = "empId"),
            @Mapping(source = "emp.name",target = "empName"),
            @Mapping(source = "emp.email",target = "empEmail")
    })
    DeptCategoryDTO entity2dto(DeptCategory dept, Employee emp);
}

当有多个entity时需要在source属性值指定时用属性名.属性的方式。
测试结果:在这里插入图片描述
自动生成的实现类:

package com.chen.test.conver;

import com.chen.test.dto.DeptCategoryDTO;
import com.chen.test.entity.DeptCategory;
import com.chen.test.entity.Employee;
import javax.annotation.Generated;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-11-12T15:24:49+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_211 (Oracle Corporation)"
)
@Component
public class DeptCategoryConverImpl implements DeptCategoryConver {

    @Override
    public DeptCategoryDTO entity2dto(DeptCategory dept, Employee emp) {
        if ( dept == null && emp == null ) {
            return null;
        }

        DeptCategoryDTO deptCategoryDTO = new DeptCategoryDTO();

        if ( dept != null ) {
            deptCategoryDTO.setDeptName( dept.getName() );
            deptCategoryDTO.setDeptId( dept.getId() );
            deptCategoryDTO.setDeptCode( dept.getCode() );
        }
        if ( emp != null ) {
            deptCategoryDTO.setEmpId( emp.getId() );
            deptCategoryDTO.setEmpName( emp.getName() );
            deptCategoryDTO.setEmpEmail( emp.getEmail() );
        }

        return deptCategoryDTO;
    }
}

补:
(1)单一属性映射:

@Mapping(source="",target="")

source指定源(entity)中的属性,target指定目标(dto)属性。
(2) 多属性映射:

@Mappings({
        @Mapping(source = "dept.id",target = "deptId"),
        @Mapping(source = "dept.code",target = "deptCode")
})

多个@Mapping(…)用逗号隔开,最后一个不带逗号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Spring Boot是一个用于创建基于Java的应用程序的框架,MapStruct一个Java注解处理器,可以用来简化Java Bean之间的映射。在Spring Boot中使用MapStruct可以帮助我们快速、方便地进行对象之间的转换。 首先,我们需要在pom.xml文件中添加MapStruct的依赖: ```xml <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.4.2.Final</version> </dependency> ``` 然后,在我们的转换类中,我们需要使用@Mapper注解来标记它为一个MapStruct映射器接口。接着,我们可以定义转换方法,使用@Mapping注解来指定属性的映射关系。例如,如果我们有一个Person类和一个PersonDto类,我们可以定义以下转换方法: ```java @Mapper public interface PersonConverter { PersonConverter INSTANCE = Mappers.getMapper(PersonConverter.class); @Mapping(source = "address", target = "addr") PersonDto personToPersonDto(Person person); @Mapping(source = "addr", target = "address") Person personDtoToPerson(PersonDto personDto); // 其他转换方法... } ``` 上述代码中,我们使用@Mapping注解来指定address属性和addr属性之间的映射关系。通过这样的方式,我们就可以在Spring Boot应用程序中方便地进行对象之间的转换了。 请注意,为了使MapStruct生效,我们需要确保在编译期间生映射器实现类已经正确地生。如果你遇到了问题,可以尝试在IDE中运行"clean install"命令来重新生映射器实现类。 以此为基础,你可以根据自己的需求定义更多的转换方法,以及处理集合类型的转换。使用MapStruct可以大大简化对象之间的映射工作,提高开发效率。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值