天天看點

bean 拷貝工具類Orika BeanUtils

拷貝在service 層完成 應用層之間也可用VO 傳遞 避免頻繁拷貝

細節

實驗目标

  1. 簡單對象的拷貝 ✔️
  2. 集合對象的拷貝 ✔️
  3. 内部類的拷貝 ❌
  4. 内部集合簡單類型的拷貝 ✔️
  5. 内部集合複雜類拷貝 ❌

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);

    }