工具类|将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不像现在这…

leetcode热题100.移动零

前言 作者&#xff1a;晓宜 &#x1f308;&#x1f308;&#x1f308; 个人简介&#xff1a;互联网大厂Java准入职&#xff0c;阿里云专家博主&#xff0c;csdn后端优质创作者&#xff0c;算法爱好者&#xff0c;github忠实用户 &#x1f319;&#x1f319;&#x1f319; 今天给…

暴力快速入门强化学习

强化学习算法的基本思想&#xff08;直觉&#xff09; 众所周知&#xff0c;强化学习是能让智能体实现某个具体任务的强大算法。 强化学习的基本思想是让智能体跟环境交互&#xff0c;通过环境的反馈让智能体调整自己的策略&#xff0c;从反馈中学习&#xff0c;不断学习来得到…

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

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

6-190 先序输出叶节点

本题要求按照先序遍历的顺序输出给定二叉树的叶结点。 函数接口定义: void PreorderPrintLeaves( BiTree BT ); 函数PreorderPrintLeaves应按照先序遍历的顺序输出给定二叉树BT的叶结点,格式为一个字符跟着一个空格。 裁判测试程序样例: #include<stdio.h> #inc…

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…

设计模式,简单工厂模式

23种设计模式是基于面向对象的一些编程逻辑思想&#xff0c;无意间看了看《大话设计模式》&#xff0c;我觉得还挺好玩&#xff0c;虽然设计模式我这个阶段确实可以不着急学&#xff0c;但我觉得这些内容挺吸引我的&#xff0c;反正时间也还多&#xff0c;就学着玩玩。而且设计…

Flink 架构深度解析

## 1. 引言 在当今的数据驱动世界中&#xff0c;实时数据处理变得越来越重要。Flink 提供了一个高性能、可扩展的平台&#xff0c;用于构建实时数据分析和处理应用。它支持事件时间处理和精确一次&#xff08;exactly-once&#xff09;处理语义&#xff0c;确保数据的准确性和…

Linux swapon命令教程:如何管理你的交换空间(附案例详解和注意事项)

Linux swapon命令介绍 swapon命令用于启用设备或文件中的交换空间。交换空间是当系统的物理内存不足时&#xff0c;系统会使用的一部分硬盘空间。 Linux swapon命令适用的Linux版本 swapon命令在大多数Linux发行版中都是可用的&#xff0c;包括Debian、Ubuntu、Alpine、Arch…

大模型在天体物理学研究中的辅助作用与案例分析

大模型在天体物理学研究中的辅助作用与案例分析 1. 背景介绍 天体物理学是研究宇宙中各种天体的物理性质和运动规律的科学。随着观测技术的进步&#xff0c;天体物理学家们获得了大量的数据&#xff0c;这些数据往往具有高维度、非线性、非平稳等特点&#xff0c;给传统的数据…

Struts2的工作原理是什么?Struts2中的MVC模式包含哪些核心组件?在Struts2中如何实现转发和重定向?

Struts2的工作原理是什么&#xff1f; Struts2的工作原理主要基于MVC设计模式&#xff0c;它充当Web应用框架的控制器层&#xff08;Controller&#xff09;&#xff0c;负责建立模型与视图之间的数据交互。 具体来说&#xff0c;Struts2的工作流程如下&#xff1a; 启动与加…

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

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

ubuntu20.04 安装ros1

详细介绍如何在ubuntu20.04中安装ROS系统&#xff0c;超快完成安装&#xff08;最新版教程&#xff09;_ubuntu安装ros-CSDN博客Ros noetic : XTDrone安装-CSDN博客 gazebo11卸载&#xff0c;安装gazebo9 我的ROS学习日记-环境搭建 - 知乎 需要选择分支 GitHub - ros-simulat…