拷貝在service 層完成 應用層之間也可用VO 傳遞 避免頻繁拷貝
細節
實驗目标
- 簡單對象的拷貝 ✔️
- 集合對象的拷貝 ✔️
- 内部類的拷貝 ❌
- 内部集合簡單類型的拷貝 ✔️
- 内部集合複雜類拷貝 ❌
entity實體
@Data
@AllArgsConstructor
@NoArgsConstructor
@Validated
@ToString
@Accessors(chain = true)
public class Person {
private String name;
@NonNull
private Integer age;
private List<Car> carList;
private LocalDateTime birthday;
}
@Data
public class PersonVO {
private List<Car> carList;
private LocalDateTime birthday;
}
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class Car {
private String brand;
private String type;
}
OrikaUtils
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import ma.glasnost.orika.metadata.Type;
import ma.glasnost.orika.metadata.TypeFactory;
import java.util.List;
/**
* @author koala
* @Description: orika 的工具類
* @date 2021/7/12 17:25
*/
public class OrikaUtil {
private static MapperFacade mapper = null;
static {
MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
mapper = mapperFactory.getMapperFacade();
}
/**
* 簡單的複制出新類型對象.
* <p>
* 通過source.getClass() 獲得源Class
*/
public static <S, D> D map(S source, Class<D> destinationClass) {
return mapper.map(source, destinationClass);
}
/**
* 極緻性能的複制出新類型對象.
* <p>
* 預先通過BeanMapper.getType() 靜态擷取并緩存Type類型,在此處傳入
*/
public static <S, D> D map(S source, Type<S> sourceType, Type<D> destinationType) {
return mapper.map(source, sourceType, destinationType);
}
/**
* 簡單的複制出新對象清單到ArrayList
* <p>
* 不建議使用mapper.mapAsList(Iterable<S>,Class<D>)接口, sourceClass需要反射,實在有點慢
*/
public static <S, D> List<D> mapList(Iterable<S> sourceList, Class<S> sourceClass, Class<D> destinationClass) {
return mapper.mapAsList(sourceList, TypeFactory.valueOf(sourceClass), TypeFactory.valueOf(destinationClass));
}
/**
* 極緻性能的複制出新類型對象到ArrayList.
* <p>
* 預先通過BeanMapper.getType() 靜态擷取并緩存Type類型,在此處傳入
*/
public static <S, D> List<D> mapList(Iterable<S> sourceList, Type<S> sourceType, Type<D> destinationType) {
return mapper.mapAsList(sourceList, sourceType, destinationType);
}
/**
* 簡單複制出新對象清單到數組
* <p>
* 通過source.getComponentType() 獲得源Class
*/
public static <S, D> D[] mapArray(final D[] destination, final S[] source, final Class<D> destinationClass) {
return mapper.mapAsArray(destination, source, destinationClass);
}
/**
* 極緻性能的複制出新類型對象到數組
* <p>
* 預先通過BeanMapper.getType() 靜态擷取并緩存Type類型,在此處傳入
*/
public static <S, D> D[] mapArray(D[] destination, S[] source, Type<S> sourceType, Type<D> destinationType) {
return mapper.mapAsArray(destination, source, sourceType, destinationType);
}
/**
* 預先擷取orika轉換所需要的Type,避免每次轉換.
*/
public static <E> Type<E> getType(final Class<E> rawType) {
return TypeFactory.valueOf(rawType);
}
}
實驗
集合拷貝過程中有一些值需要轉換 比如int 枚舉到string
/**
* mapList
* 一種是複寫Person的get方法
* 另一種是 在PersonVO 加一個字段 xxxStr 複寫xxx 的setxxx 方法
* 不能取同一個字段名 複制
*/
@Test
public void test59() {
ArrayList<Person> peoples = new ArrayList<>();
Person p0 = new Person("Tik",12,LocalDateTime.now());
Person p1 = new Person("Tik",12,LocalDateTime.now());
Person p2 = new Person("Tik",12,LocalDateTime.now());
peoples.add(p2);
peoples.add(p0);
peoples.add(p1);
List<PersonVO> personVOS = OrikaUtil.mapList(peoples, Person.class, PersonVO.class);
System.out.println(JSON.toJSONString(personVOS));
}
對象拷貝
@Test
public void orikaTest(){
User user = new User();
user.setId(1);
user.setPassword("123");
user.setUsername("Tom");
UserVO userVO = new UserVO();
UserVO map = OrikaUtils.map(user, userVO.getClass());
System.out.println(map.toString());
}
集合拷貝 ✔️
public static void main(String[] args) {
ArrayList<Integer> ls1 = new ArrayList<>();
ls1.add(1);
ls1.add(2);
List<Integer> ls2 = OrikaUtil.mapList(ls1, OrikaUtil.getType(Integer.class), OrikaUtil.getType(Integer.class));
System.out.println("---------------------");
System.out.println(ls2.toString());
}
對象裡面包含集合類型拷貝 ✔️
@Data
@AllArgsConstructor
public class Person {
private String name;
private Integer age;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime birthday;
private List<String> phone;
}
```javab
@Data
public class SinglePerson {
private List<String> phone;
}
@Test
public void test5(){
ArrayList<String> strings = new ArrayList<>();
strings.add("A");
strings.add("B");
Person person = new Person("2", 2, LocalDateTime.now(), strings);
SinglePerson map = OrikaUtil.map(person, OrikaUtil.getType(Person.class), OrikaUtil.getType(SinglePerson.class));
System.out.println(map);
}