类或集合的转换(model-dto之间的转换)
Posted jcjssl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类或集合的转换(model-dto之间的转换)相关的知识,希望对你有一定的参考价值。
1.User.class
package com.demo.model; import lombok.Data; /** * @date 2018/4/14 * 注意User中的name和UserVo中的username属性名不同,age的类型也不同 */ @Data public class User { private String name; private String age; private String sex; }
2.UserVo.class
package com.demo.vo; import lombok.Data; /** * @date 2018/4/14 */ @Data public class UserVo { private String username; private Integer age; private String sex; }
3.User1.class
package com.demo.model; import lombok.Data; /** * @date 2018/4/14 * 注意age的类型不同 */ @Data public class User1 { private String username; private String age; private String sex; }
4.UserVo1.class
package com.demo.vo; import lombok.Data; /** * @date 2018/4/14 */ @Data public class UserVo1 { private String username; private Integer age; private String sex; }
5.User2.class
package com.demo.model; import lombok.Data; /** * @date 2018/4/14 * 注意User中的name和UserVO中的username属性名不同,age的类型也不同 */ @Data public class User2 { private String name; private String age; private String sex; }
6.UserVo2.class
package com.demo.vo; import lombok.Data; /** * @date 2018/4/14 */ @Data public class UserVo2 { private String username; private Integer age; private String sex; }
7.pom.xml
<!-- https://mvnrepository.com/artifact/ma.glasnost.orika/orika-core --> <dependency> <groupId>ma.glasnost.orika</groupId> <artifactId>orika-core</artifactId> <version>1.5.2</version> </dependency>
8.第一种方法
/** * 1.单个类映射单个类(字段名不完全一样,类型也可以不一样) */ @Test public void userToUserVo(){ User user = new User(); user.setName("张三"); user.setAge("20"); user.setSex("男"); //1.创建MapperFactory MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); //2.先注册以下映射方式 mapperFactory.classMap(User.class, UserVo.class) //不一样的字段映射 .field("name","username") //剩余的字段映射 .byDefault() .register(); UserVo userVo = mapperFactory.getMapperFacade().map(user, UserVo.class); System.out.println(user); System.out.println(userVo); //输出结果 /* User(name=张三, age=20, sex=男) UserVo(username=张三, age=20, sex=男)*/ } /** * 2. 单个类映射单个类(字段名完全一样) */ @Test public void user1ToUserVo1(){ User1 user1 = new User1(); user1.setUsername("张三"); user1.setAge("20"); user1.setSex("男"); //1.创建MapperFactory MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); UserVo1 userVo1 = mapperFactory.getMapperFacade().map(user1, UserVo1.class); System.out.println(user1); System.out.println(userVo1); //输出结果 /* User1(username=张三, age=20, sex=男) UserVo1(username=张三, age=20, sex=男)*/ } /** * 3.集合之间的映射(字段名不完全一样,类型也可以不一样) */ @Test public void user2ListToUser2VoList(){ List<User2> user2List = new ArrayList<User2>(); User2 user2 = new User2(); user2.setName("张三"); user2.setAge("20"); user2.setSex("男"); user2List.add(user2); //1.创建MapperFactory MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); //2.手动配置不一样的属性转换 mapperFactory.classMap(User2.class,UserVo2.class) //不一样的字段映射 .field("name","username") //剩余的字段映射 .byDefault() .register(); //3.转换List List<UserVo2> userVo2List = mapperFactory.getMapperFacade().mapAsList(user2List, UserVo2.class); for (User2 user21 : user2List) { System.out.println(user21); } for (UserVo2 userVo2 : userVo2List) { System.out.println(userVo2); } //输出结果 /* User2(name=张三, age=20, sex=男) UserVo2(username=张三, age=20, sex=男)*/ }
9.第二种使用BeanMapper工具类
BeanMapper.class
1 package com.demo.util; 2 3 import ma.glasnost.orika.MapperFacade; 4 import ma.glasnost.orika.MapperFactory; 5 import ma.glasnost.orika.impl.DefaultMapperFactory; 6 import ma.glasnost.orika.metadata.Type; 7 import ma.glasnost.orika.metadata.TypeFactory; 8 import java.util.List; 9 10 11 /** 12 * 13 * @date 2018/4/14 14 * 简单封装orika, 实现深度的BeanOfClasssA<->BeanOfClassB复制 15 * 16 * 不要是用Apache Common BeanUtils进行类复制,每次就行反射查询对象的属性列表, 非常缓慢. 17 * 18 * 注意: 需要参考本模块的POM文件,显式引用orika. 19 */ 20 public class BeanMapper { 21 22 private static MapperFacade mapper; 23 24 static { 25 MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); 26 mapper = mapperFactory.getMapperFacade(); 27 } 28 29 /** 30 * 简单的复制出新类型对象. 31 * 32 * 通过source.getClass() 获得源Class 33 */ 34 public static <S, D> D map(S source, Class<D> destinationClass) { 35 return mapper.map(source, destinationClass); 36 } 37 38 /** 39 * 极致性能的复制出新类型对象. 40 * 41 * 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入 42 */ 43 public static <S, D> D map(S source, Type<S> sourceType, Type<D> destinationType) { 44 return mapper.map(source, sourceType, destinationType); 45 } 46 47 /** 48 * 简单的复制出新对象列表到ArrayList 49 * 50 * 不建议使用mapper.mapAsList(Iterable<S>,Class<D>)接口, sourceClass需要反射,实在有点慢 51 */ 52 public static <S, D> List<D> mapList(Iterable<S> sourceList, Class<S> sourceClass, Class<D> destinationClass) { 53 return mapper.mapAsList(sourceList, TypeFactory.valueOf(sourceClass), TypeFactory.valueOf(destinationClass)); 54 } 55 56 /** 57 * 极致性能的复制出新类型对象到ArrayList. 58 * 59 * 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入 60 */ 61 public static <S, D> List<D> mapList(Iterable<S> sourceList, Type<S> sourceType, Type<D> destinationType) { 62 return mapper.mapAsList(sourceList, sourceType, destinationType); 63 } 64 65 /** 66 * 简单复制出新对象列表到数组 67 * 68 * 通过source.getComponentType() 获得源Class 69 */ 70 public static <S, D> D[] mapArray(final D[] destination, final S[] source, final Class<D> destinationClass) { 71 return mapper.mapAsArray(destination, source, destinationClass); 72 } 73 74 /** 75 * 极致性能的复制出新类型对象到数组 76 * 77 * 预先通过BeanMapper.getType() 静态获取并缓存Type类型,在此处传入 78 */ 79 public static <S, D> D[] mapArray(D[] destination, S[] source, Type<S> sourceType, Type<D> destinationType) { 80 return mapper.mapAsArray(destination, source, sourceType, destinationType); 81 } 82 83 /** 84 * 预先获取orika转换所需要的Type,避免每次转换. 85 */ 86 public static <E> Type<E> getType(final Class<E> rawType) { 87 return TypeFactory.valueOf(rawType); 88 } 89 90 }
/** * 4.BeanMapper工具类只是做了BeanOfClasssA<->BeanOfClassB复制,要求字段属性名完全相同,不同则为null * 若需要属性名不同也能转换,则需要类似于上面的特殊配置,参考userToUserVo()和user2ListToUser2VoList() */ @Test public void beanMapperTest(){ //类的转换(字段属性名不一样为null,字段类型可以不一样也行) User user = new User(); user.setName("张三"); user.setAge("20"); user.setSex("男"); UserVo userVo = BeanMapper.map(user, UserVo.class); System.out.println(user); System.out.println(userVo); //输出: /*User(name=张三, age=20, sex=男) UserVo(username=null, age=20, sex=男)*/ //集合的转换(字段属性名不一样为null,字段类型可以不一样也行) List<User> userList = new ArrayList<User>(); userList.add(user); List<UserVo> userVoList = BeanMapper.mapList(userList, User.class, UserVo.class); for (User user1 : userList) { System.out.println(user1); } for (UserVo userVo1 : userVoList) { System.out.println(userVo1); } //输出: /*User(name=张三, age=20, sex=男) UserVo(username=null, age=20, sex=男)*/ }
10.第三种使用MapperFacade不需要依赖工具类BeanMapper
OrikaConfig.class
1 package com.demo.config; 2 3 import ma.glasnost.orika.MapperFacade; 4 import ma.glasnost.orika.MapperFactory; 5 import ma.glasnost.orika.impl.DefaultMapperFactory; 6 import ma.glasnost.orika.metadata.ClassMapBuilder; 7 import org.springframework.context.annotation.Bean; 8 import org.springframework.context.annotation.Configuration; 9 import java.util.LinkedList; 10 import java.util.List; 11 12 13 @Configuration 14 public class OrikaConfig { 15 16 @Bean 17 MapperFactory mapperFactory() { 18 MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build(); 19 List<ClassMapBuilder> builders = new LinkedList<>(); 20 21 for (ClassMapBuilder builder : builders) { 22 builder.byDefault().register(); 23 } 24 return mapperFactory; 25 } 26 27 @Bean 28 MapperFacade mapperFacade() { 29 MapperFacade mapper = mapperFactory().getMapperFacade(); 30 return mapper; 31 } 32 33 34 }
@Autowired
MapperFacade mapperFacade;
/** * 5.使用MapperFacade不需要依赖工具类BeanMapper,只需要如下两步 * ①写配置类OrikaConfig,加入到spring容器中 * ②@Autowired MapperFacade mapperFacade; */ @Test public void mapperFacadeTest(){ System.out.println(mapperFacade); //类的转换(字段属性名不一样为null,字段类型可以不一样也行) User user = new User(); user.setName("张三"); user.setAge("20"); user.setSex("男"); UserVo userVo = mapperFacade.map(user, UserVo.class); System.out.println(user); System.out.println(userVo); //输出结果: /*User(name=张三, age=20, sex=男) UserVo(username=null, age=20, sex=男)*/ //集合的转换(字段属性名不一样为null,字段类型可以不一样也行) List<User> userList = new ArrayList<User>(); userList.add(user); List<UserVo> userVoList = mapperFacade.mapAsList(userList, UserVo.class); for (User user1 : userList) { System.out.println(user1); } for (UserVo userVo1: userVoList) { System.out.println(userVo1); } //输出结果 /*User(name=张三, age=20, sex=男) UserVo(username=null, age=20, sex=男)*/ }
以上是关于类或集合的转换(model-dto之间的转换)的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin集合操作 ④ ( Set 集合 | 可变 Set 集合 | List 与 Set 之间相互转换 | 数组类型 )
Kotlin集合操作 ④ ( Set 集合 | 可变 Set 集合 | List 与 Set 之间相互转换 | 数组类型 )