mapstruct

大致四部:
第一步:引入依赖
第二步:新建一个抽象类或接口,并标注Mapper注解
第三步:编写转化方法
第四步:获取对象并调用方法 

@Mapper注解

默认映射规则:
(1)同名且同类型的属性,会自动映射,不同类型会尝试转化为同一类型。
(2)mapstruct会自动类型转化,支持的类型转化的类型如下:

        <1> 基本类型和他们对应的包装类型之间会自动转化;
        <2> 8中基本类型(包括他们的包装类型)和String类型之间的转化。
        <3> 日期类型和String之间转化

1、需求把UserEntity对象转化为Student对象:

三个实体类:

// Roles ===================================
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Roles {
    public Long roleId;
    public String name;
}
// Student ===================================
import lombok.AllArgsConstructor;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
@AllArgsConstructor
public class Student {
    public Long studentId;
    public String name;
    public String age;
    public String score;
    public Roles roles;
    public Date createTime;
}

// UserEntity ===================================
import lombok.AllArgsConstructor;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
@AllArgsConstructor
public class UserEntity {
    public Long userId;
    public String name;
    public Integer age;
    public Double score;
    public Roles roles;
    public String createTime;
}

引入包:

<properties>
    <org.mapstruct.version>1.4.1.Final</org.mapstruct.version>
</properties>
<!-- mapStruct 核心注解 -->
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>${org.mapstruct.version}</version>
</dependency>
<!-- mapStruct 根据接口生成实现类 -->
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>${org.mapstruct.version}</version>
    <scope>provided</scope>
</dependency>


补充:
· 获取UserConvert 对象实例两种方式:

    方式一:public static UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
                   使用:在调用类中直接通过类来掉用该实例
    方式二:在UserConvert类的@Mapper注解中添加 componentModel = "spring"
                   
使用:在调用类中可直接注入UserConvert

@SpringBootTest
class SpringbootTest1ApplicationTests {
    @Autowired
    UserConvert userConvert;
    @Test
    void convert() {
        Student student = userConvert.UserEntityToStudent(new UserEntity("lxc"));
        System.out.println(student);
    }
}

在编译的源码中,mapstruct会帮助我们在实现类上添加@Component注解

 编写抽象类或接口:

import com.example.springboottest1.domain.Student;
import com.example.springboottest1.domain.UserEntity;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
  * @Mapper 定义这是一个MapStruct对象属性转换接口,在这个类里面规定转换规则
  *         在项目构建时,会自动生成改接口的实现类,这个实现类将实现对象属性值复制
  **/
@Mapper
public abstract class UserConvert {
    // 获取UserConvert 对象实例
    public static UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
    // 把UserEntity转化为Student
    public abstract Student userConvertToStudent(UserEntity userEntity);
}

测试:

// @SpringBootTest
class SpringbootTest1ApplicationTests {
    @Test
    void convert() {
        // 提前把Roles和UserEntity填充好
        Roles roles = new Roles(2L, "学生角色");
        UserEntity userEntity = new UserEntity(1L, "lxc", 20,  "123.235", roles, new Date());
        // 调用UserConvert类进行转化
        Student student = UserConvert.INSTANCE.userConvertToStudent(userEntity);
        System.out.println(student);
    }
}

打印如下: 

 字段不同,所以studentId 为null,createTime不是正常的时间格式,Date转字符串。
 

@Mappings 和 @Mapping 注解

@Mappings是一个数组,可定义映射规则。
@Mapping是映射规则的实现。其常用方法如下:

(1)source 源对象、target 目标对象 
(2)dateFormat 日期格式化、numberFormat 数字格式化
(3)ignore 忽略某个属性(不会映射到目标对象)

color属性不会映射到目标对象。
需求二:

对于不同字段需要映射,时间格式"yyyy-MM-dd HH:mm:ss",小数点保留2位

@Mapper
public abstract class UserConvert {
    public static UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
    // 值是一个数组,类型是 Mapping
    @Mappings(value = {
            @Mapping(source = "userId", target = "studentId"),
            @Mapping(source = "createTime", target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss"),
            @Mapping(source = "score", target = "score", numberFormat = "#.00")
    })
    public abstract Student userConvertToStudent(UserEntity userEntity);
}

@AfterMapping 和@MappingTarget

对映射完的对象进行自定义处理(属性的自定义处理),标注@AfterMapping 注解的方法,会在对象映射完毕之后执行,可以在这个时机做一些处理;@MappingTarget标注在参数字段之前,标记这是映射完的目标对象。
例子:UserEntity和Student映射完之后,,我们把StudentRoles中的id改变。

@Data
@AllArgsConstructor
public class UserEntity {public Roles roles;}
@Data
@AllArgsConstructor
public class Roles {public Long roleId;public String name;}
@Data
@AllArgsConstructor
public class Student {public StudentRoles studentRoles;}
@Data
@AllArgsConstructor
public class StudentRoles {public Long roleId;public String name;}
@Mapper
public abstract class UserConvert {
    public static UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
    @Mappings(
            @Mapping(source = "roles", target = "studentRoles")
    )
    public abstract Student UserEntityToStudent(UserEntity userEntity);
    // 下边方法会在UserEntity 和Student对象映射完执行
    @AfterMapping
    public void handleAfter(UserEntity userEntity, @MappingTarget Student student){
        // 对于映射完的对象做自定义处理
        student.getStudentRoles().setRoleId(100L);
    }
}

测试:

// @SpringBootTest
class SpringbootTest1ApplicationTests {
    @Test
    void convert() {
        Roles roles = new Roles(2L, "学生角色");
        Student student = UserConvert.INSTANCE.UserEntityToStudent(new UserEntity(roles));
        System.out.println(student.getStudentRoles());
    }
}

 批量映射

@Mapper
public abstract class UserConvert {
    public static UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
    public abstract List<Student> userToStudent(List<Student> studentList); 
}

@BeanMapping

ignoreByDefault:可忽略mapstruct的默认映射行为。避免不需要的赋值、避免属性覆盖。

只会映射配置了@Mapping注解的字段。

@Mapper
public abstract class UserConvert {
    public static UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
    @BeanMapping(ignoreByDefault = true)
    public abstract Student UserEntityToStudent(UserEntity userEntity);
}

 测试:

@Test
    void convert() {
        Student student = UserConvert.INSTANCE.UserEntityToStudent(new UserEntity("lxc"));
        System.out.println(student);
    }

 结果,studentName字段没有被映射:

 添加@Mapping

@Mapper
public abstract class UserConvert {
    public static UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
    @BeanMapping(ignoreByDefault = true)
    @Mapping(source = "name", target = "studentName")
    public abstract Student UserEntityToStudent(UserEntity userEntity);
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值