MapStruct,对象装载结构工具

Posted 阿昌喜欢吃黄桃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MapStruct,对象装载结构工具相关的知识,希望对你有一定的参考价值。

MapStruct工具使用

工具名为MapStruct,用于对象与对象之间的互相转换,避免每一个字段都 get/set 造成麻烦。

MapStruct官网地址: http://mapstruct.org/

如下的演示使用到了Lombok工具,如果不熟悉的请自行了解,这里就不说了。

一、引包

<!--mapstruct-->
<dependency>
    <groupId>org.mapstruct</groupId>
    <!-- jdk8以下就使用mapstruct -->
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.2.0.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.2.0.Final</version>
</dependency>

二、demo

1、当对象属性相同

  • source源对象
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Person{
    private String name;
    private Integer age;
}
  • target目标对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PersonVo{
    private String name;
    private Integer age;
}
  • MapStructMapper接口
import org.mapstruct.Mapper;

@Mapper
public interface PersonMapMapper {
    PersonMapMapper INSTANCE = Mappers.getMapper(PersonMapMapper.class);

    PersonVo toPersonVo(Person person);
}
  • 他会自动在target/classes下生成对应MapStructMapper接口的实现类
public class PersonMapMapperImpl implements PersonMapMapper {
    public PersonMapMapperImpl() {
    }

    public PersonVo toPersonVo(Person person) {
        if (person == null) {
            return null;
        } else {
            PersonVo personVo = new PersonVo();
            personVo.setName(person.getName());
            personVo.setAge(person.getAge());
            return personVo;
        }
    }
}
  • 测试
public class test {
    public static void main(String[] args) {
        Person person = Person.builder().age(1).name("阿昌").build();
        PersonVo personVo = PersonMapMapper.INSTANCE.toPersonVo(person);
        System.out.println(personVo);
    }
}


2、当对象属性不同

  • source源对象
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Person{
    private String name;
    private Integer age;
}
  • target目标对象
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PersonVo{
    private String name123;
    private Integer age123;
}
  • MapStructMapper接口
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

@Mapper
public interface PersonMapMapper {
    PersonMapMapper INSTANCE = Mappers.getMapper(PersonMapMapper.class);

    @Mappings({
            @Mapping(source = "name",target = "name123"),
            @Mapping(source = "age",target = "age123")
    })
    PersonVo toPersonVo(Person person);
}
  • 他会自动在target/classes下生成对应MapStructMapper接口的实现类
package com.achang.fmService.testMapStruct;

public class PersonMapMapperImpl implements PersonMapMapper {
    public PersonMapMapperImpl() {
    }

    public PersonVo toPersonVo(Person person) {
        if (person == null) {
            return null;
        } else {
            PersonVo personVo = new PersonVo();
            personVo.setName123(person.getName());
            personVo.setAge123(person.getAge());
            return personVo;
        }
    }
}
  • 测试
public class test {
    public static void main(String[] args) {
        Person person = Person.builder().age(1).name("阿昌").build();
        PersonVo personVo = PersonMapMapper.INSTANCE.toPersonVo(person);
        System.out.println(personVo);
    }
}


3、如何结合springIoc容器?

添加==@Mapper(componentModel = “spring”)==

@Mapper(componentModel = "spring")//通过componentModel属性来指定环境为spirng
public interface PersonMapMapper {
    PersonMapMapper INSTANCE = Mappers.getMapper(PersonMapMapper.class);

    @Mappings({
            @Mapping(source = "name",target = "name123"),
            @Mapping(source = "age",target = "age123")
    })
    PersonVo toPersonVo(Person person);
}
  • 生成的Impl文件

发现自动生成了@Component

@Component //发现出现了@Component
public class PersonMapMapperImpl implements PersonMapMapper {
    public PersonMapMapperImpl() {
    }

    public PersonVo toPersonVo(Person person) {
        if (person == null) {
            return null;
        } else {
            PersonVo personVo = new PersonVo();
            personVo.setName123(person.getName());
            personVo.setAge123(person.getAge());
            return personVo;
        }
    }
}

下次就可以直接通过@Autowired注入使用

// 注入Mapper
@Autowired
private PersonMapMapper mapper;

@GetMapping("/test")
public String test() {
    Person person = new Person("阿昌", 1);
    PersonVo personVo = mapper.toPersonVo(person);
    return personVo.toString();
}

4、如果对象里面还有对象的情况,和多参数情况,和传入参数情况

通过Mapping中source属性中指定源对象里面属性的对象,用来隔开指定

	@Mappings({
            @Mapping(source = "user.id", target = "userId"), // 指定对象里面的属性
            @Mapping(source = "role.name", target = "roleName"), // 指定对象里面的属性
            @Mapping(source = "myRoleDesc", target = "myRoleDesc") //使用参数既可
    })
    UserRoleDto toUserRoleDto(User user, Role role,String myRoleDesc);

5、更新对象属性

MapStruct提供了另外一种方式来更新一个对象中的属性。@MappingTarget

    @Mappings({
            @Mapping(source = "id", target = "userId"),
            @Mapping(source = "username", target = "name"),
            @Mapping(source = "role.roleName", target = "roleName")
    })
    void update(User user, @MappingTarget UserRoleDto userRoleDto);

通过@MappingTarget来指定目标类是谁(谁的属性需要被更新)。@Mapping还是用来定义属性对应规则。

上面的演示就是说,从user对象中的id属性,更新到userRoleDto对象中的userId属性


6、自定义类型转换

有时候,在对象转换的时候可能会出现这样一个问题,就是源对象中的类型是Boolean类型,而目标对象类型是String类型,这种情况可以通过@Mapper的uses属性来实现:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Customer {
    private Long id;
    private String name;
    private Boolean isDisable;
}

@Data
public class CustomerDto {
    private Long id;
    private String customerName;
    private String disable;
}

定义转换规则的类:

public class BooleanStrFormat {
    public String toStr(Boolean isDisable) {
        if (isDisable) {
            return "Y";
        } else {
            return "N";
        }
    }
    public Boolean toBoolean(String str) {
        if (str.equals("Y")) {
            return true;
        } else {
            return false;
        }
    }
}

定义Mapper,@Mapper( uses = { BooleanStrFormat.class}),注意,这里的users属性用于引用之前定义的转换规则的类:

@Mapper( uses = { BooleanStrFormat.class})//使用我们自定义的转换类型规则
public interface CustomerMapper {

    CustomerMapper INSTANCES = Mappers.getMapper(CustomerMapper.class);

    @Mappings({
            @Mapping(source = "name", target = "	customerName"),
            @Mapping(source = "isDisable", target = "disable")
    })
    CustomerDto toCustomerDto(Customer customer);
}

以上是关于MapStruct,对象装载结构工具的主要内容,如果未能解决你的问题,请参考以下文章

Java对象转换与mapstruct实践

mapstruct解放Java对象转换

mapstruct对象转换工具

推荐一个 Java 实体映射工具 MapStruct

Java实体映射工具MapStruct的使用

MapStruct在项目中封装使用