带你读《2022技术人的百宝黑皮书》——MapStruct,降低无用代码的神器(5)https://developer.aliyun.com/article/1339759?groupCode=taobaotech
为转换加缓存
在上述的两个方法(extractAge和extractUserNick)中,进行了重复的String#split()操作,如果该操作更加复杂
(如从JSON串中提取内容),则会造成资源的浪费。
为此,可以给当前的converter加一个缓存字段extraFieldBufferLocal,如下例所示。在例子中,每次解析extra字 段前,先判断buffer是否存在,如果存在则使用缓存内容。
注:Mapstruct中使用xxx.INSTANT获得的转换器是单例的,因此,如果要在多线程环境中转换时加入缓存,其缓 存必须声明为ThreadLocal类型。
@Mapper public abstract class Converter { public static Converter INSTANT = Mappers.getMapper(Converter.class); /** * extra字段解析后的buffer,避免多次重复解析7 */ private final ThreadLocal<String[]> extraFieldBufferLocal = new ThreadLocal<>(); 9 @Mapping(target = "age", source = "extra", qualifiedByName = "extractAge") @Mapping(target = "userNick", source = "extra", qualifiedByName = "extractUserNick") public abstract VO convertToVO(DTO dto); 13 @Named("extractAge") public Long extractAge(String extra) { if (extraFieldBufferLocal.get() == null) { extraFieldBufferLocal.set(extractExtraField(extra)); } return Long.valueOf(extraFieldBufferLocal.get()[0]); } @Named("extractUserNick") public String extractUserNick(String extra) { if (extraFieldBufferLocal.get() == null) { extraFieldBufferLocal.set(extractExtraField(extra)); } 28 29 return extraFieldBufferLocal.get()[1]; } /** * 提取extra字段 * * @param extra extra字段 * @return extra字段的提取结果 */ public String[] extractExtraField(final String extra) { return extra.split(","); } }
子类字段互转
常用于平铺类和嵌套类之间的转换,例如,前端需要将类中的所有字段打平,就可以参考以下示例代码。
互相转换的类
@Data @Builder public class VO { private Long id; private Date gmtCreate; private Long age; private String userNick; }
VO:
DTO:
@Data public class DTO { private Long id; private Date gmtCreate; private Config config; @Data public static class Config{ private String age; private String userNick; } }
在DTO中,VO的age和userNick字段被放到了子类Config中。此时也可以使用上一节展示的自定义转换函数法进 行转换,不过MapStruct提供了一种更加直观简单的转换方法:
带你读《2022技术人的百宝黑皮书》——MapStruct,降低无用代码的神器(7)https://developer.aliyun.com/article/1339757?groupCode=taobaotech