起因

使用 mybatis-plus 操作后获得的数据类型为 Entity,但是前端界面往往需要展示一些其他的字段数据,此时就需要 将 Entity 转化为 Vo

那么他们三者的关系是什么呢?面向的使用对象不同

  • entity: 对应数据库表模型
  • vo: 对应需要返回到前端的数据模型 , 通常使用于后端返回的数据类
  • dto: 对应后台内部调用的数据模型, 通常使用于前端传入的参数类
package com.springblog.entity.vo;import lombok.Data;
import java.io.Serializable;@EqualsAndHashCode(callSuper = true)
@Data
public class BlogDto extends BlogEntity  {/*** 前端入参传入的字段*/private String otherField1;/*** 前端入参传入的字段*/private String otherField2;
}
package com.springblog.entity.vo;import lombok.Data;
import java.io.Serializable;@Data
public class BlogVo implements Serializable {private String title;/*** 后端返回的数据*/private String otherProperty;
}
package com.springblog.entity;import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;
import lombok.Data;import javax.validation.constraints.NotBlank;@Data
@TableName("m_blog")
public class BlogEntity implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Long id;private String title;private String description;private String content;private LocalDateTime created;
}

1. 将Entity转化为Vo

注意观察 Dto ,Vo,Entity的使用位置

    /*** Dto 通常为前端传入的参数类*/@GetMapping("/one")public R oneDefine(BlogDto blogDto) {BlogEntity blogEntity = blogService.queryBlogById(blogDto.getId());BlogVo blogVo = new BlogVo();BeanUtil.copyProperties(blogEntity,blogVo);blogVo.setOtherProperty("前端展示额外字段");/*** Vo 通常为后端返回的数据类*/return R.ok().put("data", blogVo);}

2. 将List<Entity> 转换为List<Vo>

如果采用最简单粗暴的方式,那么这个过程应该是这样的:

  1. 创建一个临时 ArrayList 对象
  2. 遍历 List ,并在内部调用工具类方法BeanUtil.copyProperties(source,target)每一个 Entity转化为vo
  3. 将每一个复制转换后的 voItem 通过 add()方法添加到临时创建的 List<Vo>

过于繁琐,这很不好

    @GetMapping("/list1")public R list1(@RequestBody Map<String, Object> params) {QueryWrapper<BlogEntity> queryWrapper = new QueryWrapper<>();List<BlogEntity> list = blogMapper.selectList(queryWrapper);ArrayList<BlogVo> voList = new ArrayList<>();list.forEach(item->{BlogVo voItem = new BlogVo();BeanUtil.copyProperties(item,voItem);voList.add(voItem);});return R.ok().put("data", voList);}

正确用法:封装到工具类后使用

  1. 封装后,将 Entity 转化为 Vo
 // Vo是返回给前端的数据类@GetMapping("/one")public R oneDefine(BlogDto blogDto) Long id) {BlogEntity blogEntity = blogService.queryBlogById(blogDto.getId());BlogVo blogVo = ConvertUtil.entityToVo(blogEntity, BlogVo.class);blogVo.setOtherProperty("前端展示额外字段");// Vo是返回给前端的数据类return R.ok().put("data", blogVo);}
  1. 封装后,将 List<Entity> 转换为List<Vo>
    @GetMapping("/list1")public R list1(@RequestBody Map<String, Object> params) {QueryWrapper<BlogEntity> queryWrapper = new QueryWrapper<>();List<BlogEntity> list = blogMapper.selectList(queryWrapper);List<BlogVo> blogVos = ConvertUtil.entityToVoList(list, BlogVo.class);return R.ok().put("data", blogVos);}

性能以及原理

  • 使用Spring提供的BeanUtil在日常使用足够了,如果涉及到数据量很大的情况,复制就比较耗时了,推介使用Mapstruct

  • Spring和Apache的BeanUtils则是用到了反射机制,都是浅拷贝

  • MapStruct使用注解处理器生成实现类,实现类内部是原生的new对象,然后SetXxx/getXxx方式赋值进行数据拷贝的,类似lombok

  • Apache提供的BeanUtils相对使用的较少

ConvertUtil工具类源码

package com.springblog.common.utils;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;import java.util.ArrayList;
import java.util.Collection;
import java.util.List;/*** @Author ifredom* @Description 类型转换: Entity - Vo转换* @Date 2022/5/10 15:59* @Param [params]**/
public class ConvertUtil {public static final Logger logger = LoggerFactory.getLogger(ConvertUtil.class);public static <T> T entityToVo(Object source, Class<T> target) {if (source == null) {return null;}T targetObject = null;try {targetObject = target.newInstance();BeanUtils.copyProperties(source, targetObject);} catch (Exception e) {e.printStackTrace();}return targetObject;}public static <T> List<T> entityToVoList(Collection<?> sourceList, Class<T> target) {if (sourceList == null) {return null;}List<T> targetList = new ArrayList<>(sourceList.size());try {for (Object source : sourceList) {T targetObject = target.newInstance();BeanUtils.copyProperties(source, targetObject);targetList.add(targetObject);}} catch (Exception e) {logger.error("convert error ", e);}return targetList;}
}

------ 如果文章对你有用,感谢 >>>点赞 | 收藏 <<<

java系列 - entity,vo转换相关推荐

  1. java中各种vo举例_了解JAVA中的POJO,Entity,PO,VO,DTO,DM包括代码举例展示

    标签: 首先是从概念上来说 POJO,全称Plain Ordinary Java Object,我理解为极其单纯的Java对象 一般只有属性字段,无参构造以及get和set方法,也是指那些没有从任何类 ...

  2. java中的vo 、dto 、dao--转

    原文地址:http://yinchunjian.iteye.com/blog/758196 O是跟数据库里表的映射,一个表对应一个VO  DAO是用VO来访问真实的表,对数据库的操作都在DAO中完成  ...

  3. java的(PO,VO,TO,BO,DAO,POJO)解释

    java的(PO,VO,TO,BO,DAO,POJO)解释    O/R Mapping 是 Object Relational Mapping(对象关系映射)的缩写.通俗点讲,就是将对象与关系数据库 ...

  4. java的(PO,VO,TO,BO,DAO,POJO)解释1

    java的(PO,VO,TO,BO,DAO,POJO)解释  O/R Mapping 是 Object Relational Mapping(对象关系映射)的缩写.通俗点讲,就是将对象与关系数据库绑定 ...

  5. java: PO,VO,TO,BO,DAO,POJO 解释

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. O/R Mapping 是 Object Relational Mapping(对象关系映射)的缩写 ...

  6. java的(PO,VO,TO,BO,DAO,POJO)类名包名解释

    java的(PO,VO,TO,BO,DAO,POJO)解释 action包  顾名思义请求,主要是和view 即我们所说的视图就是页面打交道,action类 是 操作方法,对于页 面Form 表单的操 ...

  7. 为什么你学不会递归?告别递归,谈谈我的一些经验 关于集合中一些常考的知识点总结 .net辗转java系列(一)视野 彻底理解cookie,session,token...

    为什么你学不会递归?告别递归,谈谈我的一些经验 可能很多人在大一的时候,就已经接触了递归了,不过,我敢保证很多人初学者刚开始接触递归的时候,是一脸懵逼的,我当初也是,给我的感觉就是,递归太神奇了! 可 ...

  8. Aspose.PDF for Java系列4-基本操作

    Aspose.PDF for Java系列4-基本操作 一.创建PDF文档 如何用Java创建PDF文件? 参考以下步骤: 初始化Document对象. 添加Page到Document对象. 创建Te ...

  9. 重新java系列之IO流

    重新java系列之IO流 内容介绍 学习目标 字符输入流 字符输入流[Reader] FileReader类 构造方法 读取字符数据 使用演示: 字符输出流 字符输出流[Writer] FileWri ...

  10. java偶校验计算代码_191120_02 Java常用加密校验转换算法汇总

    Java常用加密校验转换算法汇总 作者:邵发 官网:http://afanihao.cn/java 本文是Java学习指南系列教程的官方配套文档.内容介绍Java里的常用算法的使用,包含转换Hex / ...

最新文章

  1. R语言关系操作符:>、<=、!=、>=、==、
  2. ubuntu 关闭qq打不开的终极方法
  3. Sqoop拒绝连接错误
  4. 博客园配置windows live writer,实现本地代码高亮
  5. java 反射机制 视频_【视频笔记】Java反射机制笔记
  6. 拜占庭将军问题深入探讨
  7. 财务造假10年!贾跃亭被罚2.41亿
  8. php获取页面跳转后的页面内容,搜狗-PHP获取抓取页面获得跳转后的URL
  9. scrollTop、clientHeight、 scrollHeight...学完真的理解了
  10. 生产执行系统MES架构设计及应用架构
  11. 个人免签码支付源码+监控APP 实测搭建成功
  12. ftp 使用get命令下出现550 Failed to open file,但是使用put命令没问题的解决方法
  13. 统计学三大相关性系数:pearson,spearman,kendall
  14. OpenSSH之Windows账户访问操作
  15. 微信公众平台开发(100) 2048游戏
  16. 【数据结构与算法】专栏系列文章目录
  17. php织梦源码安装,如何安装网上下载的织梦源码
  18. 白话数字签名(3)——Web程序中的数字签名 1
  19. 仿淘宝商品详情页TabLayout+ListView
  20. Redis小应用:限时抢购

热门文章

  1. 绑定变量窥视 oracle,Oracle bind peeking(绑定变量窥视)
  2. 2022年深圳市个人所得税计算程序
  3. 生信学习——基于R的统计习题(附详细答案解读)
  4. 数据同步,数据库实时迁移同步方案,数据库同步软件
  5. 图的深度优先遍历与广度优先遍历及其复杂度分析
  6. 苹果自带相册打马赛克_科普 | 谨慎使用苹果自带的笔打码订单哦!
  7. 《从0到1上线微信小游戏》第七节 微信排行榜和好友分享功能
  8. vb与c语言数组传递,在VB中调用C/C++语言编写的dll,数组参数的传递
  9. 用crontab每隔1分钟执行一个命令行脚本
  10. Glide 的 transformation