Demo 对象如图
我们同时创建三个相同属性Vo对象
当我们使用BeanUtils进行拷贝时,会发现这样的问题
public static void main(String[] args) {
Student student = new Student();
student.setStudentName("大明");
List<Student> studentList = new ArrayList<>();
studentList.add(student);
Teacher teacher = new Teacher();
teacher.setTeacherName("张老师");
teacher.setStudentList(studentList);
List<Teacher> teacherList = new ArrayList<>();
teacherList.add(teacher);
School school = new School();
school.setSchoolName("三中");
school.setTeacherList(teacherList);
SchoolVo schoolVo = new SchoolVo();
BeanUtils.copyProperties(school, schoolVo);
System.out.println("schoolVo = " + schoolVo);
List<TeacherVo> teacherList1 = schoolVo.getTeacherList();
TeacherVo teacherVo = teacherList1.get(0);
List<StudentVo> studentList1 = teacherVo.getStudentList();
System.out.println("studentList1 = " + studentList1);
System.out.println("teacherList1 = " + teacherList1);
}
SchoolVo和School 相同的属性的值是拷贝过去了,但是SchoolVo的teacherList的泛型并不是TeacherVo 而是Teacher 所以当我们获取集合中的TeacherVo对象就会报错
针对上述这种情形,我们可以使用 OrikaMapper进行拷贝
pom
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>1.4.1</version>
</dependency>
封装的Utils
public class OrikaMapperUtils {
private static MapperFacade mapper;
static {
MapperFactory factory = new DefaultMapperFactory.Builder().build();
mapper = factory.getMapperFacade();
}
private OrikaMapperUtils() {
}
/**
* 简单的复制出新类型对象.
* <p>
* 内部实现是通过source.getClass() 获得源Class
*/
public static <S, D> D map(S source, Class<D> destinationClass) {
return mapper.map(source, destinationClass);
}
/**
* 极致性能的复制出新类型对象.
* <p>
* 预先通过{@link OrikaMapperUtils#getType(Class)} 静态获取并缓存Type类型,在此处传入
*/
public static <S, D> D map(S source, Type<S> sourceType, Type<D> destinationType) {
return mapper.map(source, sourceType, destinationType);
}
/**
* 简单的复制出新对象列表到ArrayList
* <p>
* 不建议使用{@link MapperFacade#mapAsList(Object[], Class)}} 接口, 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>
* 预先通过{@link OrikaMapperUtils#getType(Class)} 静态获取并缓存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
*
* @param destination 要复制到的目标数组
* @param source 待复制的源数据数组
* @param destinationClass 要复制到的目标数组数据元素Class
*/
public static <S, D> D[] mapArray(final D[] destination, final S[] source, final Class<D> destinationClass) {
return mapper.mapAsArray(destination, source, destinationClass);
}
/**
* 极致性能的复制出新类型对象到数组.
* <p>
* 需要预先通过{@link OrikaMapperUtils#getType(Class)} 静态获取并缓存转换所需Type类型,在此处传入
*
* @param destination 要复制到的目标数组
* @param source 待复制的源数据数组
* @param sourceType 待复制的源数据数组实例类型
* @param destinationType 要复制到的目标数组类型
*/
public static <S, D> D[] mapArray(D[] destination, S[] source, Type<S> sourceType, Type<D> destinationType) {
return mapper.mapAsArray(destination, source, sourceType, destinationType);
}
/**
* 预先获取orika转换所需要的{@link Type},避免每次复制都做转换.
*/
public static <E> Type<E> getType(final Class<E> rawType) {
return TypeFactory.valueOf(rawType);
}
}
使用示例:
通过上图 我们可以看到 已经成功转换成Vo对应的泛型
如果是对集合School进行拷贝,可以使用mapList方法 这里不再演示
注意:集合泛型不一样 但对应的字段名称 务必保持一致