springboot开发中使用VO拷贝工具简化代码
水平较高的读者直接拿走工具类:
package com.zhu.utils;
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author xiaozhu
* @date 2022年05月22日 16:25 $
*/
public class BeanCopyUtils {
private BeanCopyUtils(){
}
/*
* 单个的拷贝方法
* @author xiaozhu
* @date 2022/5/22 16:30
* @param source
* @param clazz
* @return V
*/
public static <V> V copyBean(Object source, Class<V> clazz) {
V result = null;
try {
result = clazz.newInstance();
BeanUtils.copyProperties(source, result);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/*
* List集合的拷贝方法
* @author xiaozhu
* @date 2022/5/22 16:38
* @param list
* @param clazz
* @return java.util.List<V>
*/
//第一个<O, V>是方法使用泛型, List<V>是方法的返回类型
public static <O, V> List<V> copyBeanList(List<O> list, Class<V> clazz){
return list.stream()
//先将的单个转化为拷贝的,然后直接收集程集合
.map(o -> copyBean(o, clazz))
.collect(Collectors.toList());
}
}
前言:我们知道entity实体类对应数据库表相对应,但是实际开发过程中,我们可能不会将数据库表中的每一个字段都展示给前端页面,因此我们就提取数据库表中我们前端需要展示的字段,封装成一个Vo对象。因此我们可以在得到实体类对象后,新建一个Vo对象,将实体类的对象的属性复制给Vo对象属性(相同属性的参数有时会不相同,因为我们需要和前端进行相应的约定)
Article和HotArticleVo
Article
package com.zhu.domain.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.io.Serializable;
/**
* 文章表(Article)实体类
* @author xiaozhu
* @since 2022-05-22 15:26:46
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("xiaozhu_article")
public class Article implements Serializable {
private static final long serialVersionUID = 601521902463091519L;
private Long id;
/**
* 标题
*/
private String title;
/**
* 文章内容
*/
private String content;
/**
* 文章摘要
*/
private String summary;
}
HotArticleVo
package com.zhu.domain.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class HotArticleVo {
private Long id;
//标题
private String title;
//访问量
private Long viewCount;
}
一般复制思路
说是复制,其实就是使用get、set方法进行简单的赋值
//根据文章id从数据库中查找进而得到文章对象,为了方便,同时假定该文章恰好是访问量最多的文章,即为最热文章
Article hotArticle = articleService.getById(1L);
//创建一个Vo对象
HotArticleVo hotArticleVo = new HotArticleVo();
//对每个属性进行一一赋值
hotArticleVo.setId(hotArticle.getId());
hotArticleVo.setTitle(hotArticle.getTitle());
hotArticleVo.setViewCount(hotArticle.getViewCount());
springframework.beans.BeanUtils
前面的一般复制思路过于繁琐,我们可以用spring中的BeanUtils的方法,这里我们就不详细介绍springframework中的BeanUtils中的方法的具体原理,我们只了解其简单用法。
//第一个参数为source,第二个参数为destination,即将第一个参数对象的属性复制给第二参数中的对象。
//第一个参数中的对象中多余的属性不参与复制
//要注意两个对象每一个属性的数据类型是否对应,数据类型不对应可能会出错。比如一个id的类型为String,另一个为Long。
BeanUtils.copyProperties(hotArticle, hotArticleVo);
封装成工具类
实际开发中,我们可能需要多次使用这种类似的拷贝方法,但是每次拷贝对应的场景不一定相同,因此我们可能需要写很多的copy或者copyList,这时我们可以直接将其封装成一个工具类,代码比较难懂,涉及到java泛型、class、stream()流和lambda表达式等知识点,我们会用即可。
package com.zhu.utils;
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author xiaozhu
* @date 2022年05月22日 16:25 $
*/
public class BeanCopyUtils {
private BeanCopyUtils(){
}
/*
* 单个对象的拷贝方法
* @author xiaozhu
* @date 2022/5/22 16:30
* @param source
* @param clazz
* @return V
*/
public static <V> V copyBean(Object source, Class<V> clazz) {
V result = null;
try {
result = clazz.newInstance();
BeanUtils.copyProperties(source, result);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/*
* List集合的拷贝方法
* @author xiaozhu
* @date 2022/5/22 16:38
* @param list
* @param clazz
* @return java.util.List<V>
*/
//第一个<O, V>是方法使用泛型, List<V>是方法的返回类型
public static <O, V> List<V> copyBeanList(List<O> list, Class<V> clazz){
return list.stream()
//先将stream流中的每一个元素进行拷贝,然后再收集为集合
.map(o -> copyBean(o, clazz))
.collect(Collectors.toList());
}
}
用例:
List<Article> HotArticles = hotArticleList;
List<HotArticleVo> hotArticleVos = BeanCopyUtils.copyBeanList(HotArticles, HotArticleVo.class);