po与vo互转工具类
po转vo工具类
- 1.反射调用
- 2.JSON序列化方式
- 3.注解驱动
- 4.ModelMappe
- 5.手动映射
- 6.总结
- 7.扩展方法
1.反射调用
这个方法会创建一个新的实例,并将所有公共字段复制到目标对象中,而不修改原来的实例。因此,如果目标类包含 private 或 final 字段,则需要额外的手动处理。
1.工具类
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;public class PoVoConverter<T, V> {protected final Class<T> clazz;public PoVoConverter(Class<T> clazz) {this.clazz = clazz;}public T voToPo(V vo) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {T po = clazz.newInstance();Field[] declaredFields = clazz.getDeclaredFields();for (Field declaredField : declaredFields) {declaredField.setAccessible(true);Field voField = vo.getClass().getDeclaredField(declaredField.getName());voField.setAccessible(true);declaredField.set(po, voField.get(vo));}return po;}public V poToVo(T po) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {V vo = clazz.newInstance();Field[] declaredFields = clazz.getDeclaredFields();for (Field declaredField : declaredFields) {declaredField.setAccessible(true);Field poField = po.getClass().getDeclaredField(declaredField.getName());poField.setAccessible(true);declaredField.set(vo, poField.get(po));}return vo;}
}
2.使用方式
PoVoConverter<User, UserVo> converter = new PoVoConverter<>(User.class);
User user = converter.voToPo(userVo);
UserVo userVo = converter.poToVo(user);
3.总结
优势:简单易懂,不需要任何额外配置
劣势:性能较差,因为需要多次反射调用,而且有可能遇到安全限制
2.JSON序列化方式
- 该方法使用 Jackson 库将 VO 对象转换为 JSON 字符串,并将字符串反序列化回 PO 类型,以此实现转换
- 注意:此方法的优点是效率较高,但是可能需要管理 JSON 库的依赖关系
1.工具类
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;public class PoVoConverter<T, V> {protected final Class<T> clazz;public PoVoConverter(Class<T> clazz) {this.clazz = clazz;}public T voToPo(V vo) throws IOException {ObjectMapper mapper = new ObjectMapper();return mapper.readValue(mapper.writeValueAsString(vo), TypeFactory.defaultInstance().constructType(clazz));}public V poToVo(T po) throws IOException {ObjectMapper mapper = new ObjectMapper();return mapper.readValue(mapper.writeValueAsString(po), TypeFactory.defaultInstance().constructType(clazz));}
}
2.使用方式
PoVoConverter<User, UserVo> converter = new PoVoConverter<>(User.class);
User user = converter.voToPo(userVo);
UserVo userVo = converter.poToVo(user);
3.总结
优势:高性能,适用于大数据量的情况
劣势:需要额外的 JSON 库支持,如果 JSON 字符串过大,则可能导致内存溢出
3.注解驱动
推荐使用 JSON 序列化方法,因为它具有较高的性能并且易于理解和维护。如果需要更高的安全性,可以考虑使用注解驱动方法
1.代码
@Service
@MapperScan("com.andy.mapper")
public interface UserMapper {@Mappings({@Mapping(source = "vo.id", target = "id"),@Mapping(source = "vo.name", target = "name"),@Mapping(source = "vo.age", target = "age")})User poToVo(UserVo vo);@Mappings({@Mapping(source = "id", target = "vo.id"),@Mapping(source = "name", target = "vo.name"),@Mapping(source = "age", target = "vo.age")})UserVo voToPo(User po);
}
2.总结
优势:简洁明了,易于维护。
劣势:需要使用第三方库,比如 MyBatis
4.ModelMappe
这里,模型映射器会自动检测用户类和 VO 类型上的 @Mapping 注解,并将 VO 类型映射到 PO 类型,反之亦然
1.导入坐标
<dependency><groupId>org.modelmapper</groupId><artifactId>modelmapper</artifactId><version>3.2.0</version>
</dependency>
2.使用方式
public class UserService {private ModelMapper modelMapper = new ModelMapper();public UserVo toVo(User po) {return modelMapper.map(po, UserVo.class);}public User toPo(UserVo vo) {return modelMapper.map(vo, User.class);}
}
3.总结
优势:无须手动编写映射代码,易于维护
劣势:可能导致依赖冲突
5.手动映射
这种方式就是我们常用的get()和set()
1.使用方式
public T voToPo(V vo) {T po = clazz.newInstance();po.setId(vo.getId());po.setName(vo.getName());po.setEmail(vo.getEmail());return po;
}public V poToVo(T po) {V vo = clazz.newInstance();vo.setId(po.getId());vo.setName(po.getName());vo.setEmail(po.getEmail());return vo;
}
3.总结
优势:有更多的控制权,适合特定场景
劣势:代码中有大量的get/set
6.总结
| 方法 | 缺点 | 优点 |
|---|---|---|
| 反射调用 | 性能较低,可能受到安全限制 | 简单易懂,适合小型项目 |
| JSON 序列化 | 需要额外的 JSON 库支持,可能产生大量垃圾信息 | 高效,适合大型项目 |
| 注解驱动 | 需要第三方库,复杂度较高 | 易于维护,性能良好 |
| ModelMapper | 可能导致冲突 | 无须手动编写映射代码,易于维护 |
| 手动映射 | 手动编写映射代码 | 更多控制权 |
7.扩展方法
1.BeanUtils.copyProperties();
2.UserVo userVo = JSON.parseObject(JSON.toJSONString(user), UserVo.class);
相关文章:
po与vo互转工具类
po转vo工具类 1.反射调用2.JSON序列化方式3.注解驱动4.ModelMappe5.手动映射6.总结7.扩展方法 1.反射调用 这个方法会创建一个新的实例,并将所有公共字段复制到目标对象中,而不修改原来的实例。因此,如果目标类包含 private 或 final 字段&am…...
基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(三)
员工分页查询和账号启用禁用功能 1. 员工分页查询1.1 需求分析和设计1.1.1 产品原型1.1.2 接口设计 1.2 代码开发1.2.1 设计DTO类1.2.2 封装PageResult1.2.3 Controller层1.2.4 Service层接口1.2.5 Service层实现类1.2.6 Mapper层 1.3 功能测试1.4 代码完善 2. 启用禁用员工账号…...
PyCharm:2023新版PyCharm无UI工具栏,如何回旧版
pycharm2023.3新版本,默认使用新UI,界面突然变化很大,感觉用起来很不适应。。。。于是,在网上搜了一下,确实有回老版的方法,试了一下,确实很nice~~~~ 方法: Settings——>Appea…...
阿里云国际站:云备份
文章目录 一、阿里云云备份的概念 二、云备份的优势 三、云备份的功能 四、云备份的应用场景 一、阿里云云备份的概念 云备份作为阿里云统一灾备平台,是一种简单易用、敏捷高效、安全可靠的公共云数据管理服务,可以为阿里云ECS整机、ECS数据库、文件…...
C#中.NET 6.0 Windows窗体应用通过EF访问数据库并对数据库追加、删除记录
目录 一、应用程序设计 二、应用程序源码 三、生成效果 前文作者发布了在.NET 6.0 控制台应用中通过EF访问已有数据库,事实上,在.NET 6.0 Windows窗体应用中通过EF访问已有数据库也是一样的。操作方法基本一样,数据库EF模型和上下文都是自…...
kafka+ubuntu20.04+docker配置
记录一次配置过程 安装docker 参加下面链接的第一部分 Ubuntu20.04使用docker安装kafka服务-CSDN博客 安装zookeeper docker run -d --name zookeeper -p 2181:2181 -v /etc/localtime:/etc/localtime wurstmeister/zookeeper安装kafka服务 docker run -d --name kafka …...
遍历一个对象,并得出所对应的值
var dates {//定义的对象year:now.getFullYear(),month:now.getMonth()1,date:now.getDate(),hour:now.getHours(),minute:now.getMinutes(),second:now.getSeconds() }//开始遍历循环 var val; for (val in dates){console.log(对象名称:val-对象的值:…...
WGCLOUD的特点整理
做运维工作很多年了,项目中用过不少的运维软件工具,今天整理下WGCLOUD的特点(优点) 首先WGCLOUD是完全免费的 部署使用:部署简单方便,上手容易,几乎没有学习成本,对新手友好 文档…...
新版软考高项试题分析精选(三)
请点击↑关注、收藏,本博客免费为你获取精彩知识分享!有惊喜哟!! 1、项目整体管理要综合考虑项目各个相关过程,围绕整体管理特点,以下说法中,( )是不正确的。 A.项目的…...
从申请服务器到Docker部署Java项目至最后运行完结
目录 1.申请服务器篇 2.配置安全组篇 3.Docker安装篇 4.代码编写打包篇 目录结构 Maven Controller DockerFile 开始打包 5.所需文件上传及镜像构建篇 上传准备 上传jar包及DockerFile文件 指令构建 验证 6.镜像启动服务验证篇 启动镜像 使用云服务器地址进行…...
解决 requests.post 数据字段编码问题的方法
问题背景 在进行网络请求时,我们通常会使用requests库的post方法来发送POST请求。然而,当我们尝试发送包含特殊字符(如中文字符)的数据时,可能会遇到数据字段被编码的问题。这可能会导致请求失败或者服务器无法正确解…...
安全运维:cmd命令大全(108个)
1、calc:启动计算器 2、appwiz.cpl:程序和功能 3、certmgr.msc:证书管理实用程序 4、charmap:启动字符映射表 5、chkdsk.exe:Chkdsk磁盘检查(管理员身份运行命令提示符) 6、cleanmgr: 打开磁盘清理工具 7、clico…...
构建Docker基础镜像(ubuntu20.04+python3.9.10+pytorch-gpu-cuda11.8)
文章目录 一、前置条件1.创建 ubuntu 镜像源文件【sources.list】2.下载 python 安装包【Python-3.9.10.tgz】 二、构建方法1.构建目录2.创建DockerFile3.打包镜像 一、前置条件 配置一下 ubuntu 的镜像源下载 python 安装包 1.创建 ubuntu 镜像源文件【sources.list】 内容…...
Flowable自定义Id生成器
内置ID生成器 Flowable内置DbIdGenerator(数据库自增ID)、StrongUuidGenerator(UUID),Flowable默认使用的StrongUuidGenerator看起来太长不好观察数据,可以修改成DbIdGenerator。 Configuration public class FlowableConfig implements EngineConfigu…...
怎样正确选择等保测评机构开展等保测评工作?
随着大家对网络安全的重视,越来越多的企业需要做等保测评了。很多小伙伴想知道怎样正确选择等保测评机构开展等保测评工作?这里就给大家简单说说。 怎样正确选择等保测评机构开展等保测评工作? 【回答】:正确选择等保测评机构开展…...
【论文阅读笔记】Detecting AI Trojans Using Meta Neural Analysis
个人阅读笔记,如有错误欢迎指出! 会议:2021 S&P Detecting AI Trojans Using Meta Neural Analysis | IEEE Conference Publication | IEEE Xplore 问题: 当前防御方法存在一些难以实现的假设,或者要求直…...
【PyTorch教程】如何使用PyTorch分布式并行模块DistributedDataParallel(DDP)进行多卡训练
本期目录 1. 导入核心库2. 初始化分布式进程组3. 包装模型4. 分发输入数据5. 保存模型参数6. 运行分布式训练7. DDP完整训练代码 本章的重点是学习如何使用 PyTorch 中的 Distributed Data Parallel (DDP) 库进行高效的分布式并行训练。以提高模型的训练速度。 1. 导入核心库 D…...
Istio学习笔记-体验istio
参考Istio 入门(三):体验 Istio、微服务部署、可观测性 - 痴者工良 - 博客园 (cnblogs.com) 在本章中,我们将会学习到如何部署一套微服务、如何使用 Istio 暴露服务到集群外,并且如何使用可观测性组件监测流量和系统指标。 本章教程示例使用…...
fastjson 系列漏洞
目录 1、 fastjson 1.2.22-1.2.24 版本 1.1 TemplatesImpl (Feature.SupportNonPublicField) 1.2 JNDI && JdbcRowSetImpl 利⽤链 2、fastjson 1.2.41 3、fastjson 1.2.42/1.2.43 4、fastjson 1.2.44-1.2.45 5、fastjson 1.2.46-1.2.47版本反序列化漏洞 jackson…...
odoo前端js对象的扩展方法
odoo前端js对象的扩展方法 在 Odoo 中,你可以使用两种方法来扩展 JavaScript 对象:extends 和 patch。这两种方法在功能上有一些区别。 extends 方法: 使用 extends 方法可以创建一个新的 JavaScript 对象,并继承自现有的对象。这…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
