SpringBoot的MapStruct使用

本文介绍了如何使用MapStruct库在Java中实现对象间的转换,包括引入依赖、创建实体类和DTO、定义转换接口、处理属性名差异以及自定义转换方法。示例展示了从Person到PersonDto的转换,反之亦然,以及列表转换,并提供了针对不同属性类型的自定义转换策略。
摘要由CSDN通过智能技术生成

目的:MapStruct可以实现对象之间的转换

一、引入依赖

<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<!--mapstruct-->
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.5.2.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.5.2.Final</version>
</dependency>

二、创建两个实体类 Person和PersonDto

import lombok.*;

/**
 * @author qinxun
 * @date 2023-06-05
 * @Descripion: 人实体类
 */
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person {

    private Long id;

    private String name;

    private Integer age;

}
import lombok.*;

/**
 * @author qinxun
 * @date 2023-06-05
 * @Descripion: 人的dto类
 */
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class PersonDto {

    private Long id;

    private String name;

    private Integer age;

}

三、创建MapStruct对象转换接口

import com.example.quartzdemo.bean.Person;
import com.example.quartzdemo.dto.PersonDto;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import java.util.List;

/**
 * @author qinxun
 * @date 2023-06-05
 * @Descripion: 人的对象mapstruct转换类
 */
@Mapper
public interface PersonConverter {

    // 使用工厂方法获取对象实例
    PersonConverter INSTANCE = Mappers.getMapper(PersonConverter.class);

    PersonDto personToPersonDto(Person person);

    Person personDtoToPerson(PersonDto personDto);

    List<PersonDto> personToPersonDto(List<Person> personList);

    List<Person> personDtoToPerson(List<PersonDto> personDtoList);

}

四、测试

import com.example.quartzdemo.bean.Person;
import com.example.quartzdemo.convert.PersonConverter;
import com.example.quartzdemo.dto.PersonDto;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
class QuartzDemoApplicationTests {

    /**
     * person转PersonDto
     */
    @Test
    void personToPersonDto() {
        Person person = new Person(1L, "张三", 25);
        PersonDto personDto = PersonConverter.INSTANCE.personToPersonDto(person);
        // 输出PersonDto(id=1, name=张三, age=25)
        System.out.println(personDto);
    }

    /**
     * personDto转Person
     */
    @Test
    void personDtoToPerson() {
        PersonDto personDto = new PersonDto(2L, "李四", 26);
        Person person = PersonConverter.INSTANCE.personDtoToPerson(personDto);
        // 输出Person(id=2, name=李四, age=26)
        System.out.println(person);
    }

    /**
     * personList转PersonDtoList
     */
    @Test
    void personListToPersonDtoList() {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person(1L, "张三", 25));
        personList.add(new Person(2L, "李四", 26));
        List<PersonDto> personDtoList = PersonConverter.INSTANCE.personToPersonDto(personList);
        // 输出[PersonDto(id=1, name=张三, age=25), PersonDto(id=2, name=李四, age=26)]
        System.out.println(personDtoList);
    }

    /**
     * PersonDtoList转personList
     */
    @Test
    void prsonDtoListToPersonList() {
        List<PersonDto> personDtoList = new ArrayList<>();
        personDtoList.add(new PersonDto(1L, "张三", 25));
        personDtoList.add(new PersonDto(2L, "李四", 26));
        List<Person> personList = PersonConverter.INSTANCE.personDtoToPerson(personDtoList);
        // 输出[Person(id=1, name=张三, age=25), Person(id=2, name=李四, age=26)]
        System.out.println(personList);
    }

}

五、如果遇到两个实体类属性名不相同的情况,我们需要对转换器接口进行处理

import java.io.Serializable;

/**
 * @author qinxun
 * @date 2023-06-05
 * @Descripion: 人实体类
 */
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person implements Serializable {

    private Long id;

    private String name;

    private Integer age;

    private String address;
    

}

import lombok.*;

/**
 * @author qinxun
 * @date 2023-06-05
 * @Descripion: 人的dto类
 */
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class PersonDto {

    private Long id;

    private String name;

    private Integer age;

    private String addr;

}

两个对象的address和addr代表同一个意思,但是表现形式不一样。

我们需要对转换接口进行映射处理

import com.example.quartzdemo.bean.Person;
import com.example.quartzdemo.dto.PersonDto;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

import java.util.List;

/**
 * @author qinxun
 * @date 2023-06-05
 * @Descripion: 人的对象mapstruct转换类
 */
@Mapper
public interface PersonConverter {

    // 使用工厂方法获取对象实例
    PersonConverter INSTANCE = Mappers.getMapper(PersonConverter.class);

    // source:需要转换的属性 target:转换后的属性
    @Mappings({
            @Mapping(source = "address", target = "addr")
    })
    PersonDto personToPersonDto(Person person);

    @Mappings({
            @Mapping(source = "addr", target = "address")
    })
    Person personDtoToPerson(PersonDto personDto);

    @Mappings({
            @Mapping(source = "address", target = "addr")
    })
    List<PersonDto> personToPersonDto(List<Person> personList);

    @Mappings({
            @Mapping(source = "addr", target = "address")
    })
    List<Person> personDtoToPerson(List<PersonDto> personDtoList);

}

测试:

import com.example.quartzdemo.bean.Person;
import com.example.quartzdemo.convert.PersonConverter;
import com.example.quartzdemo.dto.PersonDto;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
class QuartzDemoApplicationTests {

    /**
     * person转PersonDto
     */
    @Test
    void personToPersonDto() {
        Person person = new Person(1L, "张三", 25, "广州");
        PersonDto personDto = PersonConverter.INSTANCE.personToPersonDto(person);
        // 输出PersonDto(id=1, name=张三, age=25, addr=广州)
        System.out.println(personDto);
    }

    /**
     * personDto转Person
     */
    @Test
    void personDtoToPerson() {
        PersonDto personDto = new PersonDto(2L, "李四", 26, "广州");
        Person person = PersonConverter.INSTANCE.personDtoToPerson(personDto);
        // 输出Person(id=2, name=李四, age=26, address=广州)
        System.out.println(person);
    }

    /**
     * personList转PersonDtoList
     */
    @Test
    void personListToPersonDtoList() {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person(1L, "张三", 25, "广州"));
        personList.add(new Person(2L, "李四", 26, "广州"));
        List<PersonDto> personDtoList = PersonConverter.INSTANCE.personToPersonDto(personList);
        // 输出[PersonDto(id=1, name=张三, age=25, addr=广州), PersonDto(id=2, name=李四, age=26, addr=广州)]
        System.out.println(personDtoList);
    }

    /**
     * PersonDtoList转personList
     */
    @Test
    void prsonDtoListToPersonList() {
        List<PersonDto> personDtoList = new ArrayList<>();
        personDtoList.add(new PersonDto(1L, "张三", 25, "广州"));
        personDtoList.add(new PersonDto(2L, "李四", 26, "广州"));
        List<Person> personList = PersonConverter.INSTANCE.personDtoToPerson(personDtoList);
        // 输出[Person(id=1, name=张三, age=25, address=广州), Person(id=2, name=李四, age=26, address=广州)]
        System.out.println(personList);
    }

}

六、自定义转换 对于某些类型,没有办法通过代码生成器来进行处理,就需要自定义方法来进行转换。

import java.io.Serializable;

/**
 * @author qinxun
 * @date 2023-06-05
 * @Descripion: 人实体类
 */
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person implements Serializable {

    private Long id;

    private String name;

    private Integer age;

    private String address;

    private SubPerson subPerson;


}

@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class SubPerson {

    private Integer deleted;

    private String name;

}
import lombok.*;

/**
 * @author qinxun
 * @date 2023-06-05
 * @Descripion: 人的dto类
 */
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class PersonDto {

    private Long id;

    private String name;

    private Integer age;

    private String addr;

    private SubPersonDto subPersonDto;
}

@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class SubPersonDto {

    private Boolean result;

    private String name;

}

转换接口中添加自定义的转换方法

import com.example.quartzdemo.bean.Person;
import com.example.quartzdemo.bean.SubPerson;
import com.example.quartzdemo.dto.PersonDto;
import com.example.quartzdemo.dto.SubPersonDto;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

import java.util.List;

/**
 * @author qinxun
 * @date 2023-06-05
 * @Descripion: 人的对象mapstruct转换类
 */
@Mapper
public interface PersonConverter {

    // 使用工厂方法获取对象实例
    PersonConverter INSTANCE = Mappers.getMapper(PersonConverter.class);

    // source:需要转换的属性 target:转换后的属性
    @Mappings({
            @Mapping(source = "address", target = "addr"),
            @Mapping(source = "subPerson", target = "subPersonDto")
    })
    PersonDto personToPersonDto(Person person);

    @Mappings({
            @Mapping(source = "addr", target = "address"),
            @Mapping(source = "subPersonDto", target = "subPerson")
    })
    Person personDtoToPerson(PersonDto personDto);

    @Mappings({
            @Mapping(source = "address", target = "addr"),
            @Mapping(source = "subPerson", target = "subPersonDto")
    })
    List<PersonDto> personToPersonDto(List<Person> personList);

    @Mappings({
            @Mapping(source = "addr", target = "address"),
            @Mapping(source = "subPersonDto", target = "subPerson")
    })
    List<Person> personDtoToPerson(List<PersonDto> personDtoList);

    /**
     * 属性的自定义转换
     */
    default SubPersonDto subPersonToSubPersonDto(SubPerson subPerson) {
        if (subPerson == null) {
            return null;
        }
        SubPersonDto subPersonDto = new SubPersonDto();
        subPersonDto.setResult(!subPerson.getDeleted().equals(0));
        subPersonDto.setName(subPerson.getName());
        return subPersonDto;
    }

    /**
     * 属性的自定义转换
     */
    default SubPerson subPersonDtoToSubPerson(SubPersonDto subPersonDto) {
        if (subPersonDto == null) {
            return null;
        }
        SubPerson subPerson = new SubPerson();
        subPerson.setDeleted(subPersonDto.getResult() ? 1 : 0);
        subPerson.setName(subPersonDto.getName());
        return subPerson;
    }
}

测试

import com.example.quartzdemo.bean.Person;
import com.example.quartzdemo.bean.SubPerson;
import com.example.quartzdemo.convert.PersonConverter;
import com.example.quartzdemo.dto.PersonDto;
import com.example.quartzdemo.dto.SubPersonDto;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
class QuartzDemoApplicationTests {

    /**
     * person转PersonDto
     */
    @Test
    void personToPersonDto() {
        SubPerson subPerson = new SubPerson(0, "zhangsan");
        Person person = new Person(1L, "张三", 25, "广州", subPerson);
        PersonDto personDto = PersonConverter.INSTANCE.personToPersonDto(person);
        // 输出PersonDto(id=1, name=张三, age=25, addr=广州, subPersonDto=SubPersonDto(result=false, name=zhangsan))
        System.out.println(personDto);
    }

    /**
     * personDto转Person
     */
    @Test
    void personDtoToPerson() {
        SubPersonDto subPersonDto = new SubPersonDto(false, "lisi");
        PersonDto personDto = new PersonDto(2L, "李四", 26, "广州", subPersonDto);
        Person person = PersonConverter.INSTANCE.personDtoToPerson(personDto);
        // 输出Person(id=2, name=李四, age=26, address=广州, subPerson=SubPerson(deleted=0, name=lisi))
        System.out.println(person);
    }

    /**
     * personList转PersonDtoList
     */
    @Test
    void personListToPersonDtoList() {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person(1L, "张三", 25, "广州", new SubPerson(0, "zhangsan")));
        personList.add(new Person(2L, "李四", 26, "广州", new SubPerson(1, "lisi")));
        List<PersonDto> personDtoList = PersonConverter.INSTANCE.personToPersonDto(personList);
        // 输出[PersonDto(id=1, name=张三, age=25, addr=广州, subPersonDto=SubPersonDto(result=false, name=zhangsan)), PersonDto(id=2, name=李四, age=26, addr=广州, subPersonDto=SubPersonDto(result=true, name=lisi))]
        System.out.println(personDtoList);
    }

    /**
     * PersonDtoList转personList
     */
    @Test
    void prsonDtoListToPersonList() {
        List<PersonDto> personDtoList = new ArrayList<>();
        personDtoList.add(new PersonDto(1L, "张三", 25, "广州", new SubPersonDto(false, "zhangsan")));
        personDtoList.add(new PersonDto(2L, "李四", 26, "广州", new SubPersonDto(true, "lisi")));
        List<Person> personList = PersonConverter.INSTANCE.personDtoToPerson(personDtoList);
        // 输出[Person(id=1, name=张三, age=25, address=广州, subPerson=SubPerson(deleted=0, name=zhangsan)), Person(id=2, name=李四, age=26, address=广州, subPerson=SubPerson(deleted=1, name=lisi))]
        System.out.println(personList);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qinxun2008081

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值