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=男)*/ }
