Java中性能超越各个BeanUtils的Object对象属性映射框架MapStruct常规使用方式和技巧
创始人
2024-06-03 11:45:52
0

文章目录

  • 1. MapStruct使用方式
  • 2. 为什么选择MapStruct
  • 3. 使用说明
    • 3.1 对接Spring框架
    • 3.2 @Mapping的使用
      • 3.2.1 target和source
      • 3.2.2 dateFormat属性
      • 3.2.3 numberFormat属性
      • 3.2.4 constant属性
      • 3.2.5 expression属性
      • 3.2.6 ignore属性
    • 3.3 @Context的使用
      • 3.3.1 集合传递自定义参数
      • 3.3.2 函数式编程实现自定义功能

1. MapStruct使用方式

引入maven:

org.mapstructmapstruct1.4.2.Final
org.mapstructmapstruct-processor1.4.2.Final

使用mapstruct-jdk8编译可能会报java: Couldn't retrieve @Mapper annotation错误,替换成mapstruct即可。

MapStruct使用方式十分简单,创建一个interface类,并编写转换方法:

@Mapper
public interface TestMapStruct {TestMapStruct INSTANCE = Mappers.getMapper(TestMapStruct.class);ClassB aToB(ClassA a);
}

假设ClassAClassB的字段名称一模一样。使用时直接调用方法即可:

ClassB b = TestMapStruct.INSTANCE.aToB(a);

这样就能完成不同类相同字段的属性映射,十分简单。

IDEA推荐下载MapStruct Support插件,以方便看到MapStruct的注解提示。

2. 为什么选择MapStruct

TestMapStruct接口为例,MapStruct的底层原理是生成一个新类TestMapStructImpl实现TestMapStruct接口,并根据规则实现aToB方法,在aToB方法中自动根据两个类的字段名生成对应的settergetter方法,最终达到由我们自己编写settergetter方法一样的效果。因此从原理上而言,MapStruct调用时的性能和我们自己编写settergetter方法性能基本无任何差异,这是其它的BeanUtil实现方式无可比拟的。

换句话说,MapStruct的作用就是在编译时为我们自动生成对应的settergetter方法。这样的实现方式效率从本质上就已经超越了各个BeanUtil运行时根据反射动态赋值。

3. 使用说明

3.1 对接Spring框架

对接Spring框架官方提供了支持,只需要按以下配置即可:

@Mapper(componentModel = "spring")
public interface TestMapStruct {...
}public class Test {@Autowiredprivate TestMapStruct testMapStruct;
}

设置了componentModel="spring"后生成的实现类将会被@Component注解注释,并由Spring加载到容器中使用。

3.2 @Mapping的使用

如果需要复制属性的两个类存在部分字段名称或类型不一致时,可使用@Mapping注解来进行手动的映射。

3.2.1 target和source

赋值属性,target为目标字段,source为来源字段,target一定不能为空。名称不一致时可指定target和source名称,如:

public class ClassA {private String a;
}public class ClassB {private String b;
}@Mapper(componentModel = "spring")
public interface TestMapStruct {@Mapping(target = "b", source = "a");ClassB aToB(ClassA classA);
}

3.2.2 dateFormat属性

支持将Date属性以日期格式转成String

返回给前端的Vo类有createTime属性,为String类型,但数据库实体类型为Date,此时可以使用该属性将Date自动以某种格式转成String,如:

public class ClassA {private Date a;
}public class ClassB {private String b;
}@Mapper(componentModel = "spring")
public interface TestMapStruct {@Mapping(target = "b", source = "a", dateFormat = "yyyy");ClassB aToB(ClassA classA);
}

dateFormat使用SimpleDateFormat实现。

3.2.3 numberFormat属性

支持使用DecimalFormat方式将数字转换成String。如:

public class ClassA {private double a;
}public class ClassB {private String b;
}@Mapper(componentModel = "spring")
public interface TestMapStruct {@Mapping(target = "b", source = "a", numberFormat = "#.##元");ClassB aToB(ClassA classA);
}

3.2.4 constant属性

赋值属性,不能和其它赋值属性一起使用,配置该属性时会默认为新生成的类设置常量值。如:

public class ClassA {private String a;
}public class ClassB {private String b;
}@Mapper(componentModel = "spring")
public interface TestMapStruct {@Mapping(target = "b", constant = "这是B属性");ClassB aToB(ClassA classA);
}

3.2.5 expression属性

赋值属性,这个属性决定了MapStruct的可扩展性,不能和其它赋值一起使用,支持按expression = "java(java语句)"的方式来设置字段需要执行的java语句。如:

public class ClassA {private String a;
}public class ClassB {private String b;
}@Mapper(componentModel = "spring")
public interface TestMapStruct {@Mapping(target = "b", constant = "java()");ClassB aToB(ClassA classA);
}

3.2.6 ignore属性

配置忽略target属性,如:

public class ClassA {private String a;
}public class ClassB {private String b;
}@Mapper(componentModel = "spring")
public interface TestMapStruct {@Mapping(target = "b", ignore = true);ClassB aToB(ClassA classA);
}

3.3 @Context的使用

@Context注解的参数将会作为方法的上下文传递到其它方法中,使用expression的java语法可对其进行操作。

3.3.1 集合传递自定义参数

MapStruct不支持集合映射时直接传递自定义参数,如下:

public class ClassA {private String a;private String test;
}public class ClassB {private String b;private String test;
}@Mapper(componentModel = "spring")
public interface TestMapStruct {/** 支持 */@Mapping(target = "b", ignore = true);List aToB(List classA);/** 不支持 */@Mapping(target = "b", ignore = true);List aToB(List classA, String test);
}

上面的的方式在编译时会报错。此时可以使用@Context注解来实现,如下:

public class ClassA {private String a;private String test;
}public class ClassB {private String b;private String test;
}@Mapper(componentModel = "spring")
public interface TestMapStruct {@Mapping(target = "b", ignore = true);@Mapping(target = "test", expression = "java(test)");List aToB(List classA, @Context String test);
}

3.3.2 函数式编程实现自定义功能

假设此时有个场景,需要对某个参数进行转换,但转换逻辑较为复杂,需要调用另一个实现类方法来完成,此时我们就可以使用@Context+expression来实现这种复杂的功能。如下:

public class ClassA {private String a;private String test;
}public class ClassB {private String b;private String test;
}@Mapper(componentModel = "spring")
public interface TestMapStruct {@Mapping(target = "b", ignore = true);@Mapping(target = "test", expression = "java(test.apply(classA))");List aToB(List classA, @Context Function test);
}

在调用时则只需要根据函数接口Function的操作方式传入对应的逻辑即可。@Contextexpression的组合可实现的功能非常多,这种使用方式只是抛砖引玉,Function完全也可以传入其它的实现类,在expression中编写调用方式也能实现。@Contextexpression组合基本能覆盖开发时的应用场景了。

如果要学习MapStruct的更多使用方式,推荐阅读MapStruct官方文档。

上一篇:20230314 ax

下一篇:MQTT之mosquitto

相关内容

热门资讯

我的家乡大草原作文400字四... 我的家乡大草原作文400字四年级29篇 篇一:美丽的大草原我的家乡是一片美丽的大草原。大草原上绿草如...
神奇的魔法球四年级作文(最新... 神奇的魔法球四年级作文 篇一一天放学后,我在回家的路上发现了一个闪闪发光的球,它看起来非常神奇。我好...
我的榜样四年级作文(优选6篇... 我的榜样四年级作文 篇一我的榜样是我的爸爸。他是一个非常勤劳和有责任心的人。我记得有一次,我生病了,...
春风化雨润物无声抒情作文(优... 春风化雨润物无声抒情作文 篇一春天的来临,带来了温暖的春风和细雨,仿佛是大自然对万物的滋润和呵护。这...
我的妈妈四年级作文【实用6篇... 我的妈妈四年级作文 篇一我亲爱的妈妈妈妈是我最亲爱的人,她是我的好朋友,也是我的榜样。我非常喜欢和妈...
擦玻璃四年级作文200字【优... 擦玻璃四年级作文200字 篇一擦玻璃今天放学后,我回到家里看到妈妈正在擦玻璃。看到窗户上的灰尘,我忍...
游作文四年级400字【精选6... 游作文四年级400字 篇一我的暑假游记今年暑假,我和爸爸妈妈一起去了杭州旅行。这是我第一次去杭州,我...
我和孙悟空过一天四年级作文4... 我和孙悟空过一天四年级作文400字 篇一我和孙悟空过一天今天我和孙悟空一起度过了一个令人难忘的一天。...
四年级下册语文书词盘(推荐3... 四年级下册语文书词盘 篇一《小兔乖乖》词盘《小兔乖乖》是四年级下册语文书中的一篇课文,通过小兔乖乖的...
四年级下册作文(推荐5篇) 四年级下册作文 篇一:我的暑假生活我的暑假生活非常充实而有趣。虽然疫情的影响让我不能外出旅游,但我在...
游鹰嘴岩记四年级作文400字... 游鹰嘴岩记四年级作文400字 篇一游鹰嘴岩记我和家人去游鹰嘴岩的经历真是太让人难以忘怀了!鹰嘴岩位于...
游横店秦皇宫小学四年级作文4... 游横店秦皇宫小学四年级作文400字 篇一:探秘横店秦皇宫今天,我去横店秦皇宫参观了,真是被这座宫殿深...
我的同学-小学四年级写人作文... 我的同学-小学四年级写人作文 篇一我的同学小明我有一个非常好的同学,他的名字叫小明。小明是一个非常聪...
作文 好记性不如烂笔头【通用... 作文 好记性不如烂笔头 篇一好记性不如烂笔头,这是一句古训,意味着记忆力再好也不如写下来的好处。在我...
小学生作文四年级400字假期... 小学生作文四年级400字假期回顾 篇一我的暑假暑假终于来了,我迫不及待地迈入了一个充满欢乐和挑战的假...
美丽的安家沟四年级作文(精选... 美丽的安家沟四年级作文 篇一安家沟是我家乡一个美丽的小村庄,它位于山脚下,四周环绕着郁郁葱葱的树林,...
四年级童话作文(精选6篇) 四年级童话作文 篇一:《小兔子的冒险之旅》从前有一只可爱的小兔子,它叫小白。小白住在一个美丽的森林里...
小家庭大变化四年级作文【经典... 小家庭大变化四年级作文 篇一四年级的我,经历了一次小家庭的大变化。这个变化发生在我上小学的第一年,让...
小小动物园四年级作文【最新6... 小小动物园四年级作文 篇一我的家乡有一个小小动物园,里面有各种各样的动物,每次我去都会看到很多有趣的...
我的乐园四年级下册作文200... 我的乐园四年级下册作文200字 篇一我的乐园我家的后院是我的乐园,这里有我最喜欢的花草和小动物。每天...