# conversion-tool **Repository Path**: li_sicheng/conversion-tool ## Basic Information - **Project Name**: conversion-tool - **Description**: 常用java类转换工具使用案例 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-06-17 - **Last Updated**: 2021-06-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## MapStrut和Dozer的使用与区别 ### *MapStrut*:apple: *** ##### 0. 准备 *** > 添加依赖 ```xml org.mapstruct mapstruct org.mapstruct mapstruct-processor ``` > 实体对象 ```java public class User { /** * 用户ID */ private Long id; /** * 用户名称 */ private String name; /** * 用户年龄 */ private Integer age; /** * 用户性别 */ private Integer sex; /** * 手机号码 */ private String mobile; /** * 账号 */ private String account; /** * 密码 */ private String password; /** * 注册时间 */ private LocalDateTime createTime; // getter setter } ``` ```java public class Order { private Long id; private BigDecimal price; // getter setter } ``` > 枚举 ```java public enum SexEnum { /** * 性别枚举 */ MALE(1, "男"), FEMALE(2, "女"); SexEnum(int code, String desc) { this.code = code; this.desc = desc; } private int code; private String desc; public static SexEnum getSexEnumByCode(int code) { for (SexEnum sexEnum : SexEnum.values()) { if (sexEnum.getCode() == code) { return sexEnum; } } return null; } // getter } ``` > DTO ```java public class UserDTO { private Long id; private String time; // getter setter } ``` > VO ```java public class UserVO { /** * 用户ID */ private Long id; /** * 用户名称 */ private String name; /** * 用户年龄 */ private Integer age; /** * 手机号码 */ private String mobile; /** * 注册时间 */ private LocalDateTime registrationTime; // getter setter } ``` ```java public class AddSexUserVO { /** * 用户ID */ private Long id; /** * 用户名称 */ private String name; /** * 用户年龄 */ private Integer age; /** * 手机号码 */ private String mobile; /** * 注册时间 */ private LocalDateTime registrationTime; /** * 用户性别 */ private SexEnum sex; // getter setter } ``` ```java public class OrderVO { private Long id; private String price; // getter setter } ``` ##### 1. 基本使用 *** ###### 1.1 构建方法 - 在转换接口使用`Mappers.getMapper()`获取实例对象 ```java BasicConvert INSTANCE = Mappers.getMapper(BasicConvert.class); ``` - 指定注解`componentModel`属性为spring,表示将类注入到spring容器中 ```java @Mapper(componentModel = "spring") ``` ###### 1.2 基本使用 ```java // 构建方式1 @Mapper(componentModel = "spring", // 导入类,后面会用到,这里先忽略 imports = {LocalDateTime.class, SexEnum.class}) public interface BasicConvert { /** * 构建方式2 */ BasicConvert INSTANCE = Mappers.getMapper(BasicConvert.class); /** * 基本使用 * * @param user 源对象 * @return 转换对象 */ UserVO userToUserVO(User user); } ``` > 编写测试代码:tada: ```java @SpringBootTest class BasicConvertTest { @Resource private BasicConvert basicConvert; private final User user = new User(1L, "小明", 18, 1, "17673109969", "17673109969", "123456", LocalDateTime.now()); private final LocalDateTime localDateTime = LocalDateTime.of(1970, 1, 1, 0, 0, 0); @Test void example() { UserVO userVO = null; Assertions.assertNull(userVO); // 构建方式1使用方式 // userVO = basicConvert.userToUserVO(user); // 构建方式2使用方式 userVO = BasicConvert.INSTANCE.userToUserVO(user); Assertions.assertNotNull(userVO); Assertions.assertEquals(user.getMobile(), userVO.getMobile()); Assertions.assertEquals(user.getName(), userVO.getName()); System.out.println("Uer:" + JSON.toJSONString(user)); System.out.println("UserVO:" + JSON.toJSONString(userVO)); } } ``` > 运行结果:shell: ```json Uer:{"account":"17673109969","age":18,"createTime":"2021-06-17T10:47:30.005","id":1,"mobile":"17673109969","name":"小明","password":"123456","sex":1} UserVO:{"age":18,"id":1,"mobile":"17673109969","name":"小明"} ``` ###### 1.3 属性名不相同 ```java /** * 属性名不相同 * * @param user 源对象 * @return 转换对象 */ @Mapping(source = "createTime", target = "registrationTime") UserVO notFiledNameToUserVO(User user); ``` > 测试代码:taco: ```java @Test void notFiledNameToUserVOTest() { UserVO userVO = basicConvert.notFiledNameToUserVO(user); Assertions.assertEquals(userVO.getRegistrationTime(), user.getCreateTime()); System.out.println("Uer:" + JSON.toJSONString(user)); System.out.println("UserVO:" + JSON.toJSONString(userVO)); } ``` > 运行结果:rabbit: ```json Uer:{"account":"17673109969","age":18,"createTime":"2021-06-17T10:56:32.344","id":1,"mobile":"17673109969","name":"小明","password":"123456","sex":1} UserVO:{"age":18,"id":1,"mobile":"17673109969","name":"小明","registrationTime":"2021-06-17T10:56:32.344"} ``` ###### 1.4 为属性设置常量值 ```java /** * 为属性设置常量值 * * @param user 源对象 * @return 创建对象 */ @Mapping(target = "name", constant = "小红") UserVO constant(User user); ``` > 测试代码:tophat: ```java @Test void constantTest() { UserVO userVO = basicConvert.constant(user); Assertions.assertNotNull(userVO); Assertions.assertEquals("小红", userVO.getName()); System.out.println("Uer:" + JSON.toJSONString(user)); System.out.println("UserVO:" + JSON.toJSONString(userVO)); } ``` > 运行结果:rabbit2: ```java Uer:{"account":"17673109969","age":18,"createTime":"2021-06-17T10:59:23.629","id":1,"mobile":"17673109969","name":"小明","password":"123456","sex":1} UserVO:{"age":18,"id":1,"mobile":"17673109969","name":"小红"} ``` ###### 1.5 忽略字段转换 ```java /** * 忽略字段转换 * * @param user 源对象 * @return 转换对象 */ @Mappings({ @Mapping(target = "sex", ignore = true), @Mapping(target = "id", ignore = true) }) AddSexUserVO ignore(User user); ``` > 测试代码:tanabata_tree: ```java @Test void ignoreTest() { AddSexUserVO userVO = basicConvert.ignore(user); Assertions.assertNull(userVO.getSex()); Assertions.assertNull(userVO.getId()); System.out.println("Uer:" + JSON.toJSONString(user)); System.out.println("UserVO:" + JSON.toJSONString(userVO)); } ``` > 运行结果:racehorse: ```json Uer:{"account":"17673109969","age":18,"createTime":"2021-06-17T11:01:58.314","id":1,"mobile":"17673109969","name":"小明","password":"123456","sex":1} UserVO:{"age":18,"mobile":"17673109969","name":"小明"} ``` ###### 1.6 设置默认值 ```java /** * 原字段值为null,设置默认值 * * @param user 源对象 * @return 转换对象 */ @Mapping(target = "id", defaultValue = "1") UserVO defaultValue(User user); ``` > 测试代码:tangerine: ```java @Test void defaultValueTest() { User user = this.user; user.setId(null); UserVO userVO = basicConvert.defaultValue(user); Assertions.assertNull(user.getId()); Assertions.assertEquals(userVO.getId(), 1L); System.out.println("Uer:" + JSON.toJSONString(user)); System.out.println("UserVO:" + JSON.toJSONString(userVO)); } ``` > 运行结果:racing_car: ```json Uer:{"account":"17673109969","age":18,"createTime":"2021-06-17T11:05:13.157","mobile":"17673109969","name":"小明","password":"123456","sex":1} UserVO:{"age":18,"id":1,"mobile":"17673109969","name":"小明"} ``` ###### 1.7 日期字段格式化 **mapstrut支持date,localdate/datetime/time 互相换行** ```java /** * 时间格式化为字符串 * * @param dateTime localdatetime * @return 转换对象 */ @Mapping(target = "time", source = "dateTime", dateFormat = "yyyy-MM-dd") UserDTO localDateTimeFormat(LocalDateTime dateTime); /** * 时间格式化为字符串 * * @param dateTime date * @return 转换对象 */ @Mapping(target = "time", source = "dateTime", dateFormat = "yyyy-MM-dd") UserDTO dateFormat(Date dateTime); ``` > 测试代码:taurus: ```java @Test void localDateTimeFormatTest() { UserDTO userDTO = basicConvert.localDateTimeFormat(localDateTime); Assertions.assertEquals(userDTO.getTime(), "1970-01-01"); System.out.println("Uer:" + JSON.toJSONString(user)); System.out.println("userDTO:" + JSON.toJSONString(userDTO)); } @Test void dateFormatTest() throws ParseException { String dateTime = "2021-06-03"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date date = simpleDateFormat.parse(dateTime); UserDTO userDTO = basicConvert.dateFormat(date); Assertions.assertEquals(userDTO.getTime(), dateTime); System.out.println("Uer:" + JSON.toJSONString(user)); System.out.println("userDTO:" + JSON.toJSONString(userDTO)); } ``` > 运行结果:radio: ```java Uer:{"account":"17673109969","age":18,"createTime":"2021-06-17T11:09:48.303","id":1,"mobile":"17673109969","name":"小明","password":"123456","sex":1} userDTO:{"time":"1970-01-01"} /* ------------------------------- */ Uer:{"account":"17673109969","age":18,"createTime":"2021-06-17T11:10:13.775","id":1,"mobile":"17673109969","name":"小明","password":"123456","sex":1} userDTO:{"time":"2021-06-03"} ``` ###### 1.8 数字格式化 ```java /** * 将数字格式化 * * @param order 源对象 * @return 转换对象 */ @Mapping(target = "price", source = "price", numberFormat = "0.00") OrderVO numberFormat(Order order); ``` 数字格式化规则[参考](https://www.jianshu.com/p/b3699d73142e) > 测试代码:taxi: ```java @Test void numberFormatTest() { Order order = new Order(1L, new BigDecimal("3.14159265432")); OrderVO orderVO = basicConvert.numberFormat(order); Assertions.assertEquals(orderVO.getPrice(), "3.14"); System.out.println("order:" + JSON.toJSONString(order)); System.out.println("orderVO:" + JSON.toJSONString(orderVO)); } ``` > 运行结果:radio_button: ```json order:{"id":1,"price":3.14159265432}orderVO:{"id":1,"price":"3.14"} ``` ###### 1.9 多参数转换 ```java /** * 多参数转换 * * @param user 源对象 * @param registrationTime 注册时间 * @return 转换对象 */ @Mapping(source = "registrationTime", target = "registrationTime") UserVO doubleFiledToUserVO(User user, LocalDateTime registrationTime); ``` > 测试代码:tea: ```java @Test void doubleFiledToUserVOTest() { UserVO userVO = basicConvert.doubleFiledToUserVO(user, localDateTime); Assertions.assertEquals(userVO.getRegistrationTime(), localDateTime); System.out.println("Uer:" + JSON.toJSONString(user)); System.out.println("UserVO:" + JSON.toJSONString(userVO)); } ``` > 运行结果:radioactive: ```java Uer:{"account":"17673109969","age":18,"createTime":"2021-06-17T11:19:57.584","id":1,"mobile":"17673109969","name":"小明","password":"123456","sex":1} UserVO:{"age":18,"id":1,"mobile":"17673109969","name":"小明","registrationTime":"1970-01-01T00:00:00"} ``` ###### 1.10 更新对象 ```java /** * 更新对象 * * @param user 源对象 * @param userVO 被更新 */ void updateUserVO(User user, @MappingTarget UserVO userVO); ``` > 测试代码:telephone: ```java @Test void updateUserVOTest() { UserVO userVO = new UserVO(); userVO.setRegistrationTime(localDateTime); basicConvert.updateUserVO(user, userVO); Assertions.assertEquals(userVO.getRegistrationTime(), localDateTime); Assertions.assertEquals(userVO.getMobile(), user.getMobile()); System.out.println("Uer:" + JSON.toJSONString(user)); System.out.println("UserVO:" + JSON.toJSONString(userVO)); } ``` > 运行结果:rage: ```json Uer:{"account":"17673109969","age":18,"createTime":"2021-06-17T11:22:36.555","id":1,"mobile":"17673109969","name":"小明","password":"123456","sex":1} UserVO:{"age":18,"id":1,"mobile":"17673109969","name":"小明","registrationTime":"1970-01-01T00:00:00"} ``` ###### 1.11 自定义表达式转换 上面提到的暂时忽略的代码,在这里体现了。在表达式中用到的类需要在imports中导入(这里只用到了`SexEnum`) ```java /** * 自定义表达式转换 *

* 需要在@Mapper中加入 imports = {LocalDateTime.class, SexEnum.class} * * @param user 源对象 * @return 转换对象 */ @Mapping(target = "sex", expression = "java(SexEnum.getSexEnumByCode(user.getSex()))") AddSexUserVO customExpressionToAddSexUserVO(User user); ``` > 测试代码:telephone_receiver: ```java @Test void customExpressionToAddSexUserVOTest() { AddSexUserVO addSexUserVO = basicConvert.customExpressionToAddSexUserVO(user); Assertions.assertNotNull(addSexUserVO.getSex()); System.out.println("Uer:" + JSON.toJSONString(user)); System.out.println("AddSexUserVO:" + JSON.toJSONString(addSexUserVO)); } ``` > 运行结果:railway_car: ```json Uer:{"account":"17673109969","age":18,"createTime":"2021-06-17T11:26:41.229","id":1,"mobile":"17673109969","name":"小明","password":"123456","sex":1} AddSexUserVO:{"age":18,"id":1,"mobile":"17673109969","name":"小明","sex":"MALE"} ``` ###### 1.12 自定义函数转换 ```java /** * 自定义函数转换 * 1. 根据目标字段类型(也就是函数返回值) * 2. 根据参数长度(等于1),类型(会做基本转换) * 3. 匹配本类的自定义函数 * * @param user 源对象 * @return 转换对象 */ @Mapping(target = "sex", source = "sex") AddSexUserVO customFunctionToAddSexUserVO(User user); /** * 构建性别枚举 * * @param sex 性别code * @return 性别枚举 */ default SexEnum buildSexEnum(int sex) { return SexEnum.getSexEnumByCode(sex); } ``` > 测试代码:telescope: ```java @Test void customToAddSexUserVOTest() { AddSexUserVO addSexUserVO = basicConvert.customFunctionToAddSexUserVO(user); Assertions.assertNotNull(addSexUserVO.getSex()); System.out.println("Uer:" + JSON.toJSONString(user)); System.out.println("AddSexUserVO:" + JSON.toJSONString(addSexUserVO)); } ``` > 运行结果:railway_track: ```json Uer:{"account":"17673109969","age":18,"createTime":"2021-06-17T11:30:58.501","id":1,"mobile":"17673109969","name":"小明","password":"123456","sex":1} AddSexUserVO:{"age":18,"id":1,"mobile":"17673109969","name":"小明","sex":"MALE"} ``` 基本使用完结撒花:yum: ##### 2. 进阶用法 *** ###### 2.0 工具类准备 ```java @Component @Named("ConvertUtil") public class ConvertUtil { private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); private final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); @Named("toJsonStr") public String toJsonStr(Object o) { return JSONObject.toJSONString(o); } @Named("toTrim") public String toTrim(String str) { if (str == null) { return null; } return str.trim(); } @Named("toMap") public Map toMap(Object o) { if (o == null) { return Collections.emptyMap(); } return JSON.parseObject(JSON.toJSONString(o), new TypeReference>() { }); } @Named("toStrByJoin") public String toStrByJoin(List list) { return list.stream().map(String::valueOf).collect(Collectors.joining(",")); } @Named("strSplit") public List strSplit(String str){ if (str == null){ return null; } return Arrays.stream(str.split(",")).collect(Collectors.toList()); } @Named("strToLocalDateTime") public LocalDateTime strToLocalDateTime(String time) { return LocalDateTime.parse(time, dateTimeFormatter); } @Named("localDateTimeToStr") public String localDateTimeToStr(LocalDateTime localDateTime) { return dateTimeFormatter.format(localDateTime); } @Named("intToStr") public String intToStr(Integer integer) { if (integer == null) { return null; } return integer.toString(); } @Named("longToStr") public String longToStr(Long l) { if (l == null) { return null; } return l.toString(); } } ``` ###### 2.1 使用自定义工具方法 当转换类使用的构建方式为spring时,使用的工具类也必须在spring容器中。使用的工具类构建方式会同转换类一致。 ```java @Mapper(componentModel = "spring", uses = {ConvertUtil.class}) public interface CustomizeConvert { /** * 使用自定义工具方法 * * @param userDTO 源对象 * @return 转换对象 */ @Mapping(source = "time", target = "createTime", qualifiedByName = "strToLocalDateTime") @SuppressWarnings("all") User userDTOToUser(UserDTO userDTO); } ``` > 测试代码:tennis: ```java @Test void qualifiedByNameTest() { UserDTO userDTO = new UserDTO(1L, dateTime); User user = customizeConvert.userDTOToUser(userDTO); Assertions.assertEquals(user.getCreateTime(), localDateTime); System.out.println("userDTO:" + JSON.toJSONString(userDTO)); System.out.println("user:" + JSON.toJSONString(user)); } ``` > 运行结果:rainbow: ```json userDTO:{"id":1,"time":"1970-01-01 00:00:00"} user:{"createTime":"1970-01-01T00:00:00","id":1} ``` ###### 2.2 反转转换 当需要转换互转时,又需要额外配置转换规则时,使用如下方法不需要额外写配置 ```java /** * 反转转换 * * @param user 源对象 * @return 转换对象 */ @InheritInverseConfiguration(name = "userDTOToUser") UserDTO userToUserDTO(User user); ``` > 测试转换 ```java @Test void InheritInverseConfigurationTest() { User user = new User(); user.setId(1L); user.setCreateTime(localDateTime); UserDTO userToUserDTO = customizeConvert.userToUserDTO(user); Assertions.assertEquals(userToUserDTO.getTime(), dateTime); System.out.println("user:" + JSON.toJSONString(user)); System.out.println("userToUserDTO:" + JSON.toJSONString(userToUserDTO)); } ``` > 执行结果:rainbow_flag: ```java user:{"createTime":"1970-01-01T00:00:00","id":1} userToUserDTO:{"id":1,"time":"1970-01-01 00:00:00"} ``` ###### 2.3 迭代转换 ```java /** * 迭代转换 * * @param list Integer * @return list String */ @IterableMapping(elementTargetType = String.class) List iterableMapping(List list); ``` > 测试代码:tent: ```java @Test void userToUserDTO() { List list = customizeConvert.iterableMapping(Lists.newArrayList(1, 2, 3, 4, 5, 6)); Assertions.assertEquals(list.size(), 6); Assertions.assertEquals(list.get(5), "6"); System.out.println(list); } ``` > 执行结果:raised_back_of_hand: ```java [1, 2, 3, 4, 5, 6] ``` ###### 2.4 迭代转换-自定义工具类方法 ```java /** * 迭代转换 * 自定义工具类方法 * * @param list 源对象 * @return 转换对象 */ @IterableMapping(qualifiedByName = "intToStr") List iterableMappingByQualifiedByName(List list); ``` > 测试代码:thermometer: ```java @Test void iterableMappingByQualifiedByNameTest() { List list = customizeConvert.iterableMappingByQualifiedByName(Lists.newArrayList(1, 2, 3, 4, 5, 6)); Assertions.assertEquals(list.size(), 6); Assertions.assertEquals(list.get(5), "6"); System.out.println(list); } ``` > 执行结果:raised_hand: ```java [1, 2, 3, 4, 5, 6] ``` ###### 2.5 map的key,value转换 可以指定key或者value的转换规则,如果是实体会自己生成默认未指定任何配置的转换方法 ```java /** * map相互转换 * * @param map 源map * @return 转换map */ @MapMapping(keyQualifiedByName = "longToStr") Map mapMapping(Map map); ``` > 测试代码:thinking: ```java @Test void mapMappingTest() { Map userMap = new HashMap<>(); userMap.put(1L, new User()); Map userVOMap = customizeConvert.mapMapping(userMap); Assertions.assertTrue(userVOMap.containsKey("1")); System.out.println("userMap:" + userMap); System.out.println("userVOMap:" + userVOMap); } ``` > 执行结果:raised_hand_with_fingers_splayed: ```java userMap:{1=User(id=null, name=null, age=null, sex=null, mobile=null, account=null, password=null, createTime=null)} userVOMap:{1=UserVO(id=null, name=null, age=null, mobile=null, registrationTime=null)} ``` 进阶用法并不代表是高级用法,也可能是不常用方法,这里只做列举,不做讨论。 *** **以下是在做这些用法时参考的一些资料,排名不分先后,感谢以下文章提供的方法以及思路~** mapstrut参考: https://www.cnblogs.com/songjn/p/13935149.html https://www.cnblogs.com/homejim/p/11306313.html https://www.cnblogs.com/homejim/p/11313128.html https://blog.csdn.net/qq_35211818/article/details/104714363 https://blog.csdn.net/zhangxianling11/article/details/106683255?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-1&spm=1001.2101.3001.4242 ### *Dozer*:green_apple: *** ##### 前言 在了解这个工具的时候,在不同的文章中,发现了两个版本的dozer,并且使用方式大同。如下图: ![image-20210617160100162](C:\Users\Lisicheng\AppData\Roaming\Typora\typora-user-images\image-20210617160100162.png) ![image-20210617155845991](C:\Users\Lisicheng\AppData\Roaming\Typora\typora-user-images\image-20210617155845991.png) ​ 可以看到两者更新时间,前者停留在了2014年,并且在前者的官网中,进入官方github托管地址后,看到`快速开始`中提供的依赖也是上图后者 ​ 所有这里只针对上图后者的用法,不讨论两者更新以及前者的使用及问题(新老更替?) ![image-20210617161226417](C:\Users\Lisicheng\AppData\Roaming\Typora\typora-user-images\image-20210617161226417.png) ​ ![image-20210617161324726](C:\Users\Lisicheng\AppData\Roaming\Typora\typora-user-images\image-20210617161324726.png) ##### 0. 准备 > 依赖 ```xml com.github.dozermapper dozer-core ``` > `POJO`还是使用`MapStrut`中定义的,只不过重新新建,不重复使用 ##### 1. 基本使用 ```java @SpringBootTest class DozerTest { private final User user = new User(1L, "小明", 18, 1, "17673109969", "17673109969", "123456", LocalDateTime.now()); Mapper mapper = DozerBeanMapperBuilder.buildDefault(); @Test void example() { UserVO userVO = mapper.map(user, UserVO.class); Assertions.assertEquals(user.getName(), userVO.getName()); System.out.println(user); System.out.println(userVO); } } ``` > 执行结果:raising_hand_man: ```java User(id=1, name=小明, age=18, sex=1, mobile=17673109969, account=17673109969, password=123456, createTime=2021-06-17T16:52:18.239) UserVO(id=1, name=小明, age=18, phone=null, registrationTime=2021-06-17T16:52:18.239) ``` ##### 2. 属性名不相同 在源对象属性处,增加`@Mapping`注解,值为目标属性名 ```java /** * 手机号码 */ @Mapping("phone") private String mobile; /** * 注册时间 */ @Mapping("registrationTime") private LocalDateTime createTime; ``` > 测试代码:thought_balloon: ```java @Test void fieldNameNotEqTest() { UserVO userVO = mapper.map(user, UserVO.class); Assertions.assertEquals(user.getName(), userVO.getName()); Assertions.assertEquals(user.getAccount(), userVO.getPhone().toString()); Assertions.assertEquals(user.getCreateTime(), userVO.getRegistrationTime()); System.out.println(user); System.out.println(userVO); } ``` > 运行结果:raising_hand_woman: ```java User(id=1, name=小明, age=18, sex=1, mobile=17673109969, account=17673109969, password=123456, createTime=2021-06-17T16:58:29.793) UserVO(id=1, name=小明, age=18, phone=17673109969, registrationTime=2021-06-17T16:58:29.793) ``` ##### 3.实体转Map ```java @Test void entityToMapTest() { LocalDateTime localDateTime = LocalDateTime.now(); UserVO userVO = new UserVO(); userVO.setId(1L); userVO.setName("小黑"); userVO.setAge(19); userVO.setPhone(17673109969L); userVO.setRegistrationTime(localDateTime); Map map = mapper.map(userVO, Map.class); Assertions.assertTrue(map.containsKey("id")); Assertions.assertTrue(map.containsKey("name")); System.out.println(map); } ``` > 运行结果:ram: ```java {registrationTime=2021-06-17T17:14:10.054, phone=17673109969, name=小黑, id=1, age=19} ``` ##### 4.Map转实体 ```java @Test void MapToEntityTest() { Map map = new HashMap<>(); map.put("id", 1L); map.put("name", "小布"); map.put("age", 20); UserVO userVO = mapper.map(map, UserVO.class); Assertions.assertEquals(userVO.getId(), map.get("id")); Assertions.assertNull(userVO.getPhone()); System.out.println(map); System.out.println(userVO); } ``` > 运行结果:ramen: ```java {name=小布, id=1, age=20} UserVO(id=1, name=小布, age=20, phone=null, registrationTime=null) ``` ##### 总结 dozer目前不支持集合之间的转换(可以自己写循环转换),也不支持复杂类型转换(可能没找到方法)。 并且注解`@Mapping`指定转换属性后,当目标对象没有指定属性,或者带有该注解的类成为目标类,源类没有 指定属性时,都会抛出异常 *** ### 两者区别 | 名称 | 是否支持复杂转换 | 是否支持自定义转换 | 转换原理 | 是否产生更多类 | 转换效率 | | -------- | ---------------- | ------------------ | ---------------------- | -------------------------- | ------------------------- | | mapstrut | Y | Y | 编译时生成get,set代码 | 是,需要编写转换类 | :small_red_triangle: | | dozer | N | N | 动态代理 | 否,只需要构建转换通用对象 | :small_red_triangle_down: | mapstrut不支持对象与map的互相转换(可以写自定义函数) **在dozer的github地址中写到** ![image-20210617175417951](C:\Users\Lisicheng\AppData\Roaming\Typora\typora-user-images\image-20210617175417951.png) ​ 该项目目前不活跃,将来很可能会被弃用。如果您希望在新建项目中使用 Dozer,我们不鼓励这样做。如果您已经使用 Dozer 一段时间了,我们建议您开始考虑迁移到另一个库,例如: - [mapstruct](https://github.com/mapstruct/mapstruct) - [modelmapper](https://github.com/modelmapper/modelmapper)