工具类|将Entity对象转为Vo/Bo对象,并指定字段绑定

工具类|将Entity对象转为Vo/Bo对象,并指定字段绑定

实体类:People和Student,Student的三个字段和People意义一样,但是字段名不完全一样,要实现对象拷贝可使用如下工具类,用到了反射。
People.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class People {private Integer id;private String name;private Integer age;private String sex;private String classNum;private String health;private String height;private String weight;
}

Student.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {private Integer stuId;private String stuName;private Integer age;
}

CommonBeanUtils.java

package cn.yto.hbd.utils;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.*;
import org.springframework.util.*;
import javax.xml.datatype.XMLGregorianCalendar;
import java.beans.PropertyDescriptor;
import java.lang.reflect.*;
import java.util.*;/*** @Description: Bean对象转化Vo对象工具类*/
@Slf4j
public abstract class CommonBeanUtils extends org.springframework.beans.BeanUtils {/*** 对象赋值:将source对象与target对象按照匹配的字段一对一复制;** @param source 源Entity* @param target 目标Vo对象* @throws BeansException*/public static void copyProps(Object source, Object target) throws BeansException {Assert.notNull(source, "Source must not be null");Assert.notNull(target, "Target must not be null");Class<?> actualEditable = target.getClass();PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);for (PropertyDescriptor targetPd : targetPds) {if (targetPd.getWriteMethod() != null) {PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());if (sourcePd != null && sourcePd.getReadMethod() != null) {try {Method readMethod = sourcePd.getReadMethod();if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {readMethod.setAccessible(true);}Object value = readMethod.invoke(source);// 这里判断以下value是否为空 当然这里也能进行一些特殊要求的处理 例如绑定时格式转换等等if (value != null) {Method writeMethod = targetPd.getWriteMethod();Type targetParameterType = writeMethod.getGenericParameterTypes()[0];// 特殊类型不再执行copy XMLGregorianCalendarif (!(targetParameterType.equals(XMLGregorianCalendar.class))) {if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {writeMethod.setAccessible(true);}writeMethod.invoke(target, value);}}} catch (Throwable ex) {log.error(ex.getMessage());throw new FatalBeanException("Could not copy properties from source to target", ex);}}}}}/*** 对象赋值:将source对象与target按照匹配的字段一一复制;** @param source 源Entity* @param target 目标Vo对象* @param props  对应字段,0或多个* @throws BeansException*/public static void copyProps(Object source, Object target, final String... props) throws BeansException {Assert.notNull(source, "Source must not be null");Assert.notNull(target, "Target must not be null");Class<?> actualEditable = target.getClass();PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);for (PropertyDescriptor targetPd : targetPds) {if (targetPd.getWriteMethod() != null) {String prop_1;String prop_2;String targetPdNameTemp = "";for (int i = 0; i < props.length; i++) {String[] params = props[i].split("=");prop_1 = params[0];prop_2 = params[1];if (Objects.equals(targetPd.getName(), prop_1)) {targetPdNameTemp = prop_2;break;}if (Objects.equals(targetPd.getName(), prop_2)) {targetPdNameTemp = prop_1;break;}}//1.将字段转换实现字段绑定;PropertyDescriptor sourcePd;//指定了的字段绑定的按绑定字段赋值if (!"".equals(targetPdNameTemp) && null != targetPdNameTemp) {sourcePd = getPropertyDescriptor(source.getClass(), targetPdNameTemp);} else {//没有指定字段的自动匹配字段名;sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());}if (sourcePd != null && sourcePd.getReadMethod() != null) {try {Method readMethod = sourcePd.getReadMethod();if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {readMethod.setAccessible(true);}Object value = readMethod.invoke(source);// 这里判断以下value是否为空 当然这里也能进行一些特殊要求的处理 例如绑定时格式转换等等if (value != null) {Method writeMethod = targetPd.getWriteMethod();Type targetParameterType = writeMethod.getGenericParameterTypes()[0];// 特殊类型不再执行copy XMLGregorianCalendarif (!(targetParameterType.equals(XMLGregorianCalendar.class))) {if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {writeMethod.setAccessible(true);}writeMethod.invoke(target, value);}}} catch (Throwable ex) {log.error(ex.getMessage());throw new FatalBeanException("Could not copy properties from source to target", ex);}}}}}/*** 集合对象转化赋值:如List<People> 转为List<Student>(实体Student的字段是People字段的子集)** @param sources 源集合对象* @param voClass vo类型* @param <T>* @return*/public static <T> List<T> copyListProps(List<? extends Object> sources, final Class<T> voClass) {Assert.isTrue(!CollectionUtils.isEmpty(sources), "Source must not be null");List<T> targets = new ArrayList<>();sources.forEach(source -> {try {T target = voClass.newInstance();copyProperties(source, target);targets.add(target);} catch (InstantiationException | IllegalAccessException e) {log.error(e.getMessage());}});return targets;}/*** 集合对象转化赋值:如List<People> 转为List<Student>(实体Student的字段是People字段的子集)** @param sources 源Entity集合对象* @param voClass vo类型.class* @param <T>* @return*/public static <T> List<T> copyListProps(List<? extends Object> sources, final Class<T> voClass, final String... props) {Assert.isTrue(!CollectionUtils.isEmpty(sources), "Source must not be null");List<T> targets = new ArrayList<>();sources.forEach(source -> {try {T target = voClass.newInstance();//调用带参数绑定的拷贝方法;copyProps(source, target, props);targets.add(target);} catch (InstantiationException | IllegalAccessException e) {log.error(e.getMessage());}});return targets;}
}

测试类:

package cn.yto.hbd.utils;public class Test0 {public static void main(String[] args) {People people = new People();Student student = new Student();people.setId(4);people.setAge(10);people.setName("张三 ");people.setClassNum("3");people.setHealth("健康000");people.setHeight("180cm");people.setWeight("60kg");people.setSex("男");CommonBeanUtils.copyProps(people,student,"stuId=id","name=stuName");System.out.println(people);System.out.println(student);}
}

运行结果:

img

运行结果

package cn.yto.hbd.utils;import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;public class BeanConvertUtils {/*** 普通转换* @param source 源* @param targetClass* @param <T>* @return*/public static  <T> T  copy(Object source,Class<T> targetClass){return copy(source ,targetClass,null);}/*** 普通转换* @param sourceObj 源* @param targetObj 目标* @param <T>* @return*/public static  <T> T  copy(Object sourceObj,T targetObj){return copy(sourceObj ,targetObj,null);}/*** 普通转换* @param source 源* @param targetClass* @param keyMap  源字段=目标字段* @return*/public static  <T> T  copy(Object source,Class<T> targetClass,String ...keyMap){T targetObj= null;try {targetObj = targetClass.getConstructor(null).newInstance(null);} catch (Exception e) {throw new RuntimeException(e);}return copy(source,targetObj,keyMap);}/*** 普通转换* @param sourceObj 源* @param targetObj 目标* @param keyMap  源字段=目标字段* @return*/public static  <T> T  copy(Object sourceObj,T targetObj,String ...keyMap){Class<?> sourceClass = sourceObj.getClass();Class<?> targetClass = targetObj.getClass();Map<String, String> keyMaps = new HashMap<>();if (keyMap!=null&&keyMap.length>0){for (String keyItem : keyMap) {String[] split = keyItem.split("=");keyMaps.put(split[0],split[1]);}}Field[] sourceFieldFields = sourceObj.getClass().getDeclaredFields();for (Field sourceField : sourceFieldFields) {String sourceFieldName = sourceField.getName();String targetFieldName=keyMaps.getOrDefault(sourceFieldName,sourceFieldName);String sourceMethodName = getGetMethodName(sourceFieldName);String targetMethodName = getSetMethodName(targetFieldName);try {Method sourceGetMethod = sourceClass.getDeclaredMethod(sourceMethodName);Method targetSetField = targetClass.getDeclaredMethod(targetMethodName,sourceField.getType());Object value = sourceGetMethod.invoke(sourceObj);targetSetField.invoke(targetObj,value);} catch (Exception e) {//找不到字段}}return targetObj;}/*** 首字母大写* @param str* @return*/private static String strFirstUpper(String str){return str.substring(0,1).toUpperCase()+str.substring(1);}/*** 获取get方法名* @param fieldName* @return*/private static String getGetMethodName(String fieldName){return "get"+strFirstUpper(fieldName);}private static String getSetMethodName(String fieldName){return "set"+strFirstUpper(fieldName);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/764755.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue3 组件之间的通信

一、父子通信 ① props 父传子&#xff08;这种传值方法是只读的&#xff0c;不可以进行修改。&#xff09; 父组件props.vue中 <template><h2>props:我是父组件</h2><hr><props-child msg"我是静态的数据" :num"num" :obj&…

Qt实现TFTP Server和 TFTP Client(一)

1 概述 TFTP协议是基于UDP的简单文件传输协议&#xff0c;协议双方为Client和Server.Client和Server之间通过5种消息来传输文件,消息前两个字节Code是消息类型&#xff0c;消息内容随消息类型不同而不同。传输模式有三种&#xff1a;octet,netascii和mail&#xff0c;octet为二…

Flask 与小程序 的图片数据交互 过程及探讨研究学习

今天不知道怎么的&#xff0c;之前拿编程浪子地作品抄过来粘上用好好的&#xff0c;昨天开始照片突的就不显示了。 今天不妨再耐味地细细探究一下微信小程序wxml 和flask服务器端是怎么jpg图片数据交互的。 mina/pages/food/index.wxml <!--index.wxml--> <!--1px …

上位机图像处理和嵌入式模块部署(qmacvisual图像识别)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 所谓图像识别&#xff0c;就是对图像进行分类处理&#xff0c;比如说判断图像上面的物体是飞机、还是蝴蝶。在深度学习和卷积神经网络CNN不像现在这…

欧科云链:2024将聚焦发展与安全,用技术助力链上数据安全和合规

近期&#xff0c;OpenAI和Web3.0两大新技术发展势头迅猛。OpenAI 再次引领AI领域的新浪潮&#xff0c;推出了创新的文本转视频模型——Sora&#xff0c;Sora 可以创建长达60 秒的视频&#xff0c;包含高度详细的场景、複杂的摄像机运动以及情感丰富角色&#xff0c;再次将AI 的…

lora-scripts 训练IP形象

CodeWithGPU | 能复现才是好算法CodeWithGPU | GitHub AI算法复现社区&#xff0c;能复现才是好算法https://www.codewithgpu.com/i/Akegarasu/lora-scripts/lora-trainstable-diffusion打造自己的lora模型&#xff08;使用lora-scripts&#xff09;-CSDN博客文章浏览阅读1.1k次…

怿星科技Neptune CHT-S测试系统,让智能座舱测试更加高效便捷

随着汽车“智能化”浪潮的推进&#xff0c;汽车的智能化水平正在持续刷新行业认知。在这股智能化潮流中&#xff0c;智能座舱作为客户体验最为直观的部分&#xff0c;其重要性不言而喻。倘若座舱设备出现死机、黑屏、卡顿等现象&#xff0c;都将对客户的使用体验产生非常大的影…

ChatGPT无法登录,提示我们检测到可疑的登录行为?如何解决?

OnlyFans 订阅教程移步&#xff1a;【保姆级】2024年最新Onlyfans订阅教程 Midjourney 订阅教程移步&#xff1a; 【一看就会】五分钟完成MidJourney订阅 GPT-4.0 升级教程移步&#xff1a;五分钟开通GPT4.0 如果你需要使用Wildcard开通GPT4、Midjourney或是Onlyfans的话&am…

c语言--内存函数的使用(memcpy、memcmp、memset、memmove)

目录 一、memcpy()1.1声明1.2参数1.3返回值1.4memcpy的使用1.5memcpy模拟使用1.6注意 二、memmove()2.1声明2.2参数2.3返回值2.4使用2.5memmove&#xff08;&#xff09;模拟实现 三、memset3.1声明3.2参数3.3返回值3.4使用 四、memcmp()4.1声明4.2参数4.3返回值4.4使用 五、注…

【python】Anaconda安装后打不开jupyter notebook(网页不自动跳出)

文章目录 一、遇到的问题&#xff1a;jupyter notebook网页不自动跳出&#xff08;一&#xff09;输入jupyter notebook命令&#xff08;二&#xff09;手动打开网页 二、解决办法&#xff1a;指定浏览器&#xff08;一&#xff09;找文件 jupyter_notebook_config.py&#xff…

自媒体用ChatGPT批量洗稿软件V5.9环境配置/软件设置教程【汇总】

大家好&#xff0c;我是淘小白~ 首先&#xff0c;感谢大家的支持~~ ChatGPT采集洗稿软件V5.9版本更新&#xff0c;此次版本更新修改增加了一些内容&#xff1a; 1、自定义多条指令&#xff0c;软件自动判断指令条数&#xff0c;进行输入 2、增加谷歌浏览多账号轮询&#xf…

读算法的陷阱:超级平台、算法垄断与场景欺骗笔记18_竞争市场

1. 竞争市场 1.1. 算法、大数据、超级平台的风起云涌似乎预示了市场竞争机制的加速终结&#xff0c;而我们似乎也对这种市场机制的衰退见怪不怪 1.1.1. 它有效节省了消费者的搜寻成本&#xff0c;降低了市场准入壁垒&#xff0c;开辟了市场扩张与准入之间的崭新通道&#xff…

Spark-Scala语言实战(5)

在之前的文章中&#xff0c;我们学习了如何在scala中定义与使用集合和元组。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言实战&#xff08;…

c++核心学习5

4.6继承 有些类与类之间存在特殊的关系&#xff0c;例如下图中&#xff1a; 我们发现&#xff0c;定义这些类时&#xff0c;下级别的成员除了拥有上一级的共性&#xff0c;还有自己的特性。这个时候我们就可以考虑利用继承的技术&#xff0c;减少重复代码 4.6.1继承的基本语法…

VTK9.2.0+Qt5.14.0 绘制点云

背景 为了显示结构光重建后的点云&#xff0c;开发QT5.14.0VTK9.2.0的上位机软件&#xff0c;用于对结构光3D相机进行控制&#xff0c;并接收传输回来的3D数据&#xff0c;显示在窗口中。 配置QT和VTK VTK9.2.0下载源码&#xff0c;用Cmake编译&#xff0c;编译好的VTK9.2.0…

去中心化的 AI 数据供应:认识Grass,参与Grass

去中心化的 AI 数据供应&#xff1a;认识Grass&#xff0c;参与Grass &#x1f44b;&#xff1a;邀请链接☘️&#xff1a;Intro❓&#xff1a;看好Grass和即将推出的L2的原因有哪些&#xff1f;&#x1f4a1;&#xff1a;展望&#x1f50d;&#xff1a;总结 &#x1f44b;&…

说说webpack的构建流程?

文章目录 一、运行流程初始化流程编译构建流程compile 编译make 编译模块build module 完成模块编译 输出流程seal 输出资源emit 输出完成 二、小结参考文献 一、运行流程 webpack 的运行流程是一个串行的过程&#xff0c;它的工作流程就是将各个插件串联起来 在运行过程中会…

python学生作业管理系统flask-django-nodejs-php

课题主要分为三大模块&#xff1a;即管理员模块和学生、教师模块&#xff0c;主要功能包括&#xff1a;学生、教师、作业信息、学习模块、教学评价、学习情况等&#xff1b; 关键词&#xff1a;学生作业管理系统&#xff1b;作业信息 目录 摘 要 I Abstrac II 目录 III 1绪论 1…

matlab实现机器学习svm

一、目的和要求 1.编程实现SVM训练函数和预测函数&#xff1b; 2.绘制线性和非线性边界&#xff1b; 3.编写线性核函数 二、算法 1.线性svm&#xff1a; 分离超平面&#xff1a;wxb0&#xff0c;对于线性可分的数据集来说&#xff0c;这样的超平面有无穷多个&#xff08;…

ARM32day4

VID_20240319_210515 1.思维导图 2.实现三个LED灯亮灭 .text .global _start _start: 使能GPIO外设时钟 LDR R0,0x50000A28 LDR R1,[R0]使能GPIOE ORR R1,R1,#(0X1<<4)使能GPIOF ORR R1,R1,#(0X1<<5) STR R1,[R0]设置引脚状态 LDR R0,0X50006000 LDR R1,[R0…