java map的结构体,MapStruct的使用介绍

MapStruct的介绍

MapStruct 是一个属性映射工具,只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了复杂繁琐的映射实现。

在一个JavaWeb工程中会涉及到多种对象,po、vo、dto、entity、do、domain这些定义的对象运用在不同的场景模块中,这种对象与对象之间的互相转换,就需要有一个专门用来解决转换问题的工具。以前是通过反射的方法实现,但是现在无论是 BeanUtils, BeanCopier 等在使用反射的时候都会影响到性能,再后来自己写装换器但是会很浪费时间, 而且在添加新的字段的时候也要进行方法的修改。

MapSturct 是一个生成类型安全, 高性能且无依赖的 JavaBean 映射代码的注解处理器。作为一个工具类,相比于手写, 其具有便捷, 不容易出错的特点。

MapStruct的使用

引入依赖

maven工程需要在pom文件中引入以下依赖

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

1.2.0.Final

org.MapStruct

MapStruct-jdk8

${org.MapStruct.version}

org.MapStruct

MapStruct-processor

${org.MapStruct.version}

基本使用

编写两个实体类

1

2

3

4

5

6

7

8

9@Data

@NoArgsConstructor

@AllArgsConstructor

public class Car{

private String make;

private int numberOfSeats;

}

1

2

3

4

5

6

7

8

9

10

11@Data

@NoArgsConstructor

@AllArgsConstructor

public class CarDto{

private String make;

private int seatCount;

private String name;

private String description;

}

编写转换接口

1

2

3

4

5

6

7

8@Mapper

public interface CarMapper{

CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );

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

CarDto carToCarDto(Car car);

}

编写测试方法

1

2

3

4

5

6

7

8

9

10public static void main(String[] args){

Car car = new Car( "测试", 10 );

//转换对象

CarDto carDto = CarMapper.INSTANCE.carToCarDto(car);

//测试

System.out.println( carDto );

System.out.println( carDto.getMake() );

System.out.println( carDto.getSeatCount() );

}

例子中使用了lombok插件, 请自行添加相关依赖和插件后使用。

MapStruct原理说明

在 target/generated-sources/annotations 里可以看到,代码中可以看到其生成了一个实现类, 而代码也类似于我们手写。

这个在编译期生成的代码,性能上是比反射要快不少的。

228c8abfe132ab3da9835f883bb84f08.gif

MapStruct是利用编译期动态生成set/get代码的class文件 ,在运行时直接调用该class文件。 该方式实际上仍会存在set/get代码,只是不需要自己手写。

MapStruct 中注解的关键词1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17@Mapper 只有在接口加上这个注解, MapStruct 才会去实现该接口

@Mapper 里有个 componentModel 属性,主要是指定实现类的类型,有如下4种方式

default: 这是默认的情况,MapStruct不使用任何组件类型, 可以通过Mappers.getMapper(Class)方式获取自动生成的实例对象。

cdi: the generated mapper is an application-scoped CDI bean and can be retrieved via @Inject。

spring: 生成的实现类上面会自动添加一个@Component注解,可以通过Spring的 @Autowired方式进行注入。

jsr330: 生成的实现类上会添加@javax.inject.Named 和@Singleton注解,可以通过 @Inject注解获取。

@Mapping:属性映射,若源对象属性与目标对象名字一致,会自动映射对应属性

source:源属性

target:目标属性

dateFormat:String 到 Date 日期之间相互转换,通过 SimpleDateFormat,该值为 SimpleDateFormat 的日期格式

numberFormat:数值格式化, 例:"0.00"

expression: 自定义java代码实现属性映射

ignore: 忽略这个字段

@Mappings:配置多个@Mapping

@MappingTarget 用于更新已有对象

@InheritConfiguration 用于继承配置

MapStruct 转换方式

属性名称相同,则进行转化。

这种类似于BeanUtils转换的方式。

属性名不相同, 可通过 @Mapping 注解进行指定转化。

例 @Mapping(source = “numberOfSeats”, target = “seatCount”)

Mapper 中使用自定义的转换

对于某些类型, 无法通过代码生成器的形式来进行处理,就需要自定义的方法来进行转换。利用java8新特性,在接口中定义一个默认方法。

1

2

3

4

5

6

7

8

9default CarDto carToCarDto2(Car car){

if (car == null) {

return null;

}

CarDto carDto = new CarDto();

carDto.setMake("China:" + car.getMake());

carDto.setSeatCount(car.getNumberOfSeats());

return carDto;

}

多个对象装换成一个对象

新建一个Brand类

1

2

3

4

5

6

7

8@Data

@NoArgsConstructor

@AllArgsConstructor

public class Brand{

private String name;

private String description;

}

添加转换方法

1CarDto carToCarDto(Car car, Brand brand);

测试方法

1

2

3

4

5

6

7

8

9Car car1 = new Car( "测试", 10 );

Brand brand = new Brand( "bwm", "宝马" );

CarDto toCarDto = CarMapper.INSTANCE.carToCarDto(car, brand);

System.out.println( toCarDto );

System.out.println( toCarDto.getMake() );

System.out.println( toCarDto.getSeatCount() );

System.out.println( toCarDto.getName() );

System.out.println( toCarDto.getDescription() );

228c8abfe132ab3da9835f883bb84f08.gif

注意:

当多个对象中, 有其中一个为 null, 则会直接返回 null

如一对一转换一样, 属性通过名字来自动匹配。 因此, 名称和类型相同的不需要进行特殊处理

当多个原对象中,有相同名字的属性时,需要通过 @Mapping 注解来具体的指定, 以免出现歧义

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值