优雅的转换工具MapStruct plus,纵享丝滑!

介绍:

        MapStruct Plus是MapStruct的增强工具,它基于MapStruct并实现了自动生成Mapper接口的功能,同时强化了部分功能,使得Java类型转换更加便捷、优雅。


一:MapStruct:

        MapStruct是一个开源的Java库,它简化了对象到对象映射的过程。这个库是一个代码生成器,基于Java注释处理器,通过定义类转换的接口,自动实现属性转换的具体逻辑。

使用步骤:

  • 添加依赖:在项目的构建文件中添加MapStruct的依赖。

  • 定义映射器接口:创建一个Java接口,并使用@Mapper注解标记。在接口中定义映射方法,这些方法将自动生成实现。

  • 配置映射规则:使用@Mapping注解配置源对象和目标对象之间的属性映射规则。如果属性名称相同,则会自动映射;如果名称不同,则可以通过@Mapping注解指定源属性和目标属性。

  • 生成映射代码:在构建项目时,MapStruct注解处理器会自动生成映射器的实现类。

  • 使用映射器:在代码中通过映射器的实例调用映射方法,将源对象转换为目标对象。

示例演示:

//定义源对象
class Student{
    private Long id;
    private String name;
}

//定义目标对象
class StudentBo{
    private Long studentId;
    private String studentName;
}

//定义映射器接口
@Mapper
public interface StudentMapper {
    CarMapper INSTANCE = Mappers.getMapper(StudentMapper.class);

    @Mapping(source = "id", target = "studentId")
    @Mapping(source = "name", target = "studentName")
    StudentBo studentToStudentBo(Student stu);
}


//使用映射器进行对象转换
@Test
public void test{
        Student stu= new Student();
        stu.setId(1L);
        stu.setName("Student转换StudentBo");

        StudentBo stuBo= CarMapper.INSTANCE.studentToStudentBo(stu);
        System.out.println(stuBo.getStudentId());      // 输出:1
        System.out.println(stuBo.getStudentName());    // 输出:Student转换StudentBo
}

缺点

  1. 需要定义映射器接口:虽然这有助于明确映射规则,但也增加了额外的代码量。
  2. 对于非常简单的映射场景,可能显得过于重量级。

二:MapStruct Plus:

        MapStruct Plus则是MapStruct的扩展或增强版本,内嵌了MapStruct,并与其完全兼容。在MapStruct的基础上进行了多项增强,提供了更高级和灵活的映射功能、更好的性能和错误处理、简化的使用体验和集成以及其他实用的增强功能。如果之前已经使用MapStruct,可以无缝替换为MapStruct Plus的依赖。


功能和特点:

  • 自动生成Mapper接口:用户只需在类上添加@AutoMapper注解,并指定目标类型,MapStruct Plus即可自动生成转换逻辑。

  • 增强的类型转换功能

    1. 支持复杂类型转换,如嵌套对象或集合的映射。

    2. 提供条件映射,根据某些条件决定是否执行映射,或使用不同的映射策略。

    3. 允许自定义转换逻辑,以处理特殊的转换需求。

  • 性能优化:MapStruct Plus可能对映射过程进行了优化,以提高大规模数据转换的性能。

  • 更好的错误处理:提供更清晰的错误消息和调试信息,帮助快速定位问题。

  • 与Lombok的整合:MapStruct Plus支持与Lombok的整合,方便开发者使用。

使用步骤:

  • 引入MapStruct Plus依赖:在项目的pom.xml文件中添加MapStruct Plus的依赖。
        <dependency>
            <groupId>io.github.linpeilie</groupId>
            <artifactId>mapstruct-plus-spring-boot-starter</artifactId>
            <version>1.3.5</version>
        </dependency>
  • 配置Maven插件:配置maven-compiler-plugin插件,以启用注解处理器。

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.11.0</version>
				<configuration>
					<source>17</source>
					<target>17</target>
                    <encoding>UTF-8</encoding>
					<annotationProcessorPaths>
						<path>
							<groupId>io.github.linpeilie</groupId>
							<artifactId>mapstruct-plus-processor</artifactId>
							<version>1.3.5</version>
						</path>
						<path>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok-mapstruct-binding</artifactId>
							<version>0.2.0</version>
						</path>
					</annotationProcessorPaths>
				</configuration>
			</plugin>
		</plugins>
	</build>
  • 定义源对象和目标对象

  • 使用生成的Mapper接口:在需要转换对象的地方,注入Converter接口,并调用其convert方法。

示例演示:

  • 定义源对象和目标对象

@Data
@AutoMapper(target = Student.class)
public class StudentBo {
    private Long id;
    private String name;
}


@Data
public class Student {
    private Long id;
    private String name;
    
}
  • 示例代码(java代码)
@SpringBootTest
public class MapstructTest {

    @Test
    public void domainConvert(){
        StudentBo studentBo = new StudentBo();
        studentBo.setId(1l);
        studentBo.setAge(20);
        studentBo.setSchool(true);
        studentBo.setName("StudentBo转Student");
        Student convert = MapstructUtils.convert(studentBo, Student.class);
        System.out.println(convert);
    }

}

//输出结果:
//Student(id=1, name=StudentBo转Student, age=20, date=null, isSchool=true)

三:更多用法

1.名称不一致:

   当对象之前字段名称不一致,使用 @AutoMapping(source = "", target = "")注解

@Data
@AutoMapper(target = Student.class)
public class StudentBo {

    private Long id;
    
    //目标字段不一致情况
    @AutoMapping(source = "name", target = "studentName")
    private String name;
}



@Data
public class Student {
    private Long id;
    private String studentName;
}

2. map转换对象

使用注解@AutoMapMapper

@Data
@AutoMapMapper
public class StudentBo {
    private Long id;
    private String name;
}

示例代码(Java代码)

@SpringBootTest
public class MapstructTest {

    
    @Test
    public void mapConvert(){
        Map<String, Object> map = new HashMap<>();
        map.put("id", 1l);
        map.put("name", "map转StudentBo");
        StudentBo convert = MapstructUtils.convert(map, StudentBo.class);
        System.out.println(convert);
    }

}

3.枚举转换

1.自定义枚举:

注解@AutoEnumMapper,指定需要转换字段state

@Getter
@AllArgsConstructor
@AutoEnumMapper("state")
public enum GoodsStateEnum {

    ENABLED(1, "启用"),
    DISABLED(0, "禁用");

    private Integer state;
    private String desc;
}

2.定义对象

//源对象
@Data
//转换目标对象GoodsVo
@AutoMapper(target = GoodsVo.class)
public class Goods {
  	//商品状态枚举
    private GoodsStateEnum state;
}

//目标对象
@Data
public class GoodsVo {
    private Integer state;
}

示例代码(Java代码)

@SpringBootTest
public class MapstructTest {

    @Test
    public void enumMapTest() {
      	//源对象,这里默认选择启用状态:1
        Goods goods = new Goods();
        goods.setState(GoodsStateEnum.ENABLED);
      	//转换GoodsVo对象
        GoodsVo goodsVo = MapstructUtils.convert(goods, GoodsVo.class);
      
      	//结果:GoodsVo(state=1)
        System.out.println(goodsVo);
    }
}

(目前版本没有看到useEnums 属性,欢迎大家测试测试并留言,互相学习一下!)

当前特性从 1.2.2 开始支持(当需要进行枚举转换时(例如枚举转换为编码值,或者由编码转换为枚举),可以在目标枚举添加 @AutoEnumMapper 注解, 增加该注解后,在任意类型中需要转换该枚举时都可以自动转换。

使用该注解需要注意:当前枚举必须有一个可以保证唯一的字段,并在使用当前注解时,将该字段名,添加到注解提供的 value 属性中。枚举和使用枚举的类,要在同一个模块中

该特性从 1.4.2 开始支持(跨模块支持,当枚举与要使用的类型,不在同一个模块(module)中时,并不能自动转换,需要指定依赖关系。在 AutoMapper 注解中,可以通过属性 useEnums 来指定,当前转换关系,需要依赖的枚举类列表。这些枚举需要被 AutoEnumMapper注解。

需要注意的是,当两个类在同一个模块(module)中,无需指定,可以自动转换。当前特性主要解决跨模块之间不能自动转换的问题。

4.一个类与多个类之间转换

官方文档:

https://www.mapstruct.plus/introduction/about.html

综上所述,MapStruct Plus在MapStruct的基础上进行了多项增强,提供了更高级和灵活的映射功能、更好的性能和错误处理、简化的使用体验和集成以及其他实用的增强功能。这使得MapStruct Plus成为处理Java对象映射的一个强大而高效的工具。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

码农小丘

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

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

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

打赏作者

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

抵扣说明:

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

余额充值