在我们写项目的时候,在dto和entity之间,以及entity和vo之间经常需要进行值的拷贝,虽然 org.springframework.beans 包下为我们提供了系统工具类 BeanUtils ,可以使用里面的 copyProperties() 的方法实现单个实体的属性拷贝,但是我们还需要一个new 的过程,接下来推荐给大家使用的工具类可省略这一步,并且可以对实体集合进行拷贝。我本人的习惯时dto接收前端传过来的数据,vo用来封装返回给前端的数据。
下面以自己做的项目中的代码为例进行详细讲解(为了代码简短,删掉一些不必要的字段和信息):
import lombok.Data;
@Data
public class Class {
private String classId;
private String courseId;
private String teacherId;
private String classInvitationCode;
private String className;
private Integer studentNumber;
}
import lombok.Data;
@Data
public class ClassVo {
private String classId;
private String classInvitationCode;
private String className;
private Integer studentNumber;
}
注:查询到一个班级信息时,我们在返回给前端不需要那么多字段,所以需要封装vo给前端
1)不使用任何工具类的情况下,代码如下:
String classId = "123"; //假设我们查找的班级id为123
Class classInfo = classMapper.selectById(classId);
ClassVo classVo = new ClassVo();
classVo.setClassId(classInfo.getClassId());
classVo.setClassName(classInfo.getClassName());
classVo.setClassInvitationCode(classInfo.getClassInvitationCode());
classVo.setStudentNumber(classInfo.getStudentNumber());
return classVo;
2)使用spring中的 BeanUtils,一行相当于注释的四行,拷贝字段越多,作用越明显,代码如下:
String classId = "123"; //假设我们查找的班级id为123
Class classInfo = classMapper.selectById(classId);
ClassVo classVo = new ClassVo();
BeanUtils.copyProperties(classInfo, classVo);
// classVo.setClassId(classInfo.getClassId());
// classVo.setClassName(classInfo.getClassName());
// classVo.setClassInvitationCode(classInfo.getClassInvitationCode());
// classVo.setStudentNumber(classInfo.getStudentNumber());
return classVo;
3)使用我们自己封装的,省去 new 的那一行,代码如下:
String classId = "24"; //假设我们查找的班级id为24
Class classInfo = classMapper.selectById(classId);
ClassVo classVo = BeanCopyUtils.copyBean(classInfo, ClassVo.class);
// ClassVo classVo = new ClassVo();
// BeanUtils.copyProperties(classInfo, classVo);
return classVo;
注:我们要查找一门课程中的多个班级,然后将班级字段的部分信息返回给前端。
1、不使用工具类
String courseId = "711";//假设课程id为711
LambdaQueryWrapper<Class> lambda = new LambdaQueryWrapper<>();
lambda.eq(Class::getCourseId, courseId).orderByDesc(Class::getUpdateTime);
List<Class> ClassList = classMapper.selectList(lambda);
List<ClassVo> classVos = new ArrayList<>();
for (Class aClass : ClassList) {
//这里使用单个拷贝工具类
ClassVo classVo = BeanCopyUtils.copyBean(aClass, ClassVo.class);
classVos.add(classVo);
}
return classVos;
2、使用我们自己的工具类,可以看到,省略了大量低效的代码
String courseId = "711";//假设课程id为711
LambdaQueryWrapper<Class> lambda = new LambdaQueryWrapper<>();
lambda.eq(Class::getCourseId, courseId).orderByDesc(Class::getUpdateTime);
List<Class> selectClasses = classMapper.selectList(lambda);
//bean拷贝,下面一行等同于之前的几行
List<ClassVo> classVos = BeanCopyUtils.copyBeanList(selectClasses, ClassVo.class);
return classVos;
下面是工具类的代码,可直接复制到您的项目。
说明:本质是对 copyProperties() 进行封装
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.stream.Collectors;
public class BeanCopyUtils {
private BeanCopyUtils() {
}
public static <V> V copyBean(Object source, Class<V> clazz) {
//创建目标对象
V result = null;
try {
result = clazz.newInstance();
//实现属性copy
BeanUtils.copyProperties(source, result);
} catch (Exception e) {
e.printStackTrace();
}
//返回结果
return result;
}
public static <O, V> List<V> copyBeanList(List<O> list, Class<V> clazz) {
return list.stream()
.map(o -> copyBean(o, clazz))
.collect(Collectors.toList());
}
}