工具类|将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.rhkb.cn/news/283076.html

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

相关文章

Spring Boot 3 极速搭建OAuth2认证框架

本篇环境 Java 17Spring Boot 3.2.3Spring Authorization Server 1.2.3开发工具 SpringToolSuite4Spring Boot 3.2.3 需要JDK 17及之上的版本。 项目初始化 项目可以使用Spring的初始化器生成, 也可以创建一个Maven类型的项目。 项目创建后的目录结构如下: 项目配置 使用 …

spring suite搭建springboot操作

一、前言 有时候久了没开新项目了&#xff0c;重新开发一个新项目&#xff0c;搭建springboot的过程都有点淡忘了&#xff0c;所有温故知新。 二、搭建步骤 从0开始搭建springboot 1&#xff0e;创建work空间。步骤FileNewJava Working Set。 2.选择Java Working Set。 3.自…

SQLiteC/C++接口详细介绍sqlite3_stmt类(九)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;八&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;十&#xff09; 33、sqlite3_column_table_name 函数 sqlite3_column_ta…

智慧城市中的智慧生活:便捷、舒适与高效

目录 一、智慧城市中的智慧生活概述 二、智慧生活带来的便捷性 1、智慧交通的便捷出行 2、智慧购物的轻松体验 3、智慧政务的一站式服务 三、智慧生活带来的舒适性 1、智慧环境的绿色宜居 2、智慧医疗的健康保障 3、智慧教育的均衡发展 四、智慧生活带来的高效性 1、…

ios symbolicatecrash 符号化crash

一、准备 1.1 .crash 文件获取 设备连接电脑 打开XCode, 依次 XCode -> Windows -> Device and Simulator -> Open Recent Logs 找到 (对应app名+时间点) -> 右键 Show in Finder 1.2 .dSYM 和 .app 文件获取 .dSYM是十六进制函数地址映射信息的中转文件,调试的…

Git原理及使用

1、Git初识 Git是一种版本控制器: 对于同一份文件,做多次改动,Git会记录每一次改动前后的文件。 通俗的讲就是⼀个可以记录⼯程的每⼀次改动和版本迭代的⼀个管理系统,同时也⽅便多⼈协同作业。 注意: Git其实只能跟踪⽂本⽂件的改动,⽐如TXT⽂件,⽹⻚,所有的程序代码…

ARM-Linux 开发板下安装编译 OpenCV 和 Dlib

安装 OpenCV 和 Dlib 不像在 x86 平台下那样简单&#xff0c;用一句命令就可以自动安装完。而在 ARM 平台中许多软件都需要自行下载编译&#xff0c;且还有许多问题&#xff0c;本篇文章就是记录在 ARM 平台下载 OpenCV 踩过的坑。 硬件环境&#xff1a; RK3568 Ubuntu20.04…

【练习】双指针算法思想

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;Java算法&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 1. 移动零 1.1 题目描述 1.2 讲解算法原理 1.3 编…

【Kafka系列】Kafka事务一般在什么场景下使用呢

面试官&#xff1a;听说你精通Kafka&#xff0c;那我就考考你吧 面试官&#xff1a;不用慌尽管说&#xff0c;错了也没关系&#x1f60a;。。。 以【面试官面试】的形式来分享技术&#xff0c;本期是《Kafka系列》&#xff0c;感兴趣就关注我吧❤️ 面试官&#xff1a;生产者重…

ideaSSM 学员信息管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 学员信息管理系统是一套完善的信息管理系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff…

现代游戏引擎架构

一、并行编程 1.1 为什么需要并行编程 游戏的渲染计算对算力要求很高&#xff0c;所以我们需要把操作系统的资源利用到极致。 但是摩尔定律已经不在适用了&#xff0c;硬件的发展目前已经达到瓶颈。所以我们需要通过数量来提高计算效率。 1.2 并行编程基础 进程与线程&#…

eclipse中使用PlantUML plugin查看对象关系

一.背景 公司安排的带徒弟任务&#xff0c;给徒弟讲了如何设计对象。他们的思维里面都是单表增删改查&#xff0c;我的脑海都是一个个对象&#xff0c;他们相互关系、各有特色本事。稳定的结构既能满足外部功能需求&#xff0c;又能在需求变更时以最小代价响应。最大程度的记录…

NIVision-相机图像采集

应用场景 上位机与工业相机通讯&#xff0c;控制相机抓取图像。 工业相机的通讯接口大多为USB口或网口。 USB口则直接将通讯线缆插入上位机USB端口&#xff0c;打开MAX中设备与接口一栏可以看到电脑给相机分配的资源名称&#xff1b;网口则需要将网线连接相机和上位机&#xf…

课时72:流程控制_for循环_嵌套循环

1.1.1 嵌套循环 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 简介 这里的嵌套实践&#xff0c;与选择语句的嵌套实践基本一致&#xff0c;只不过组合的方式发生了一些变化。常见的组合样式如下&#xff1a;for嵌套for语句for …

基于python+vue学生作业管理系统flask-django-nodejs-php

快速发展的社会中&#xff0c;人们的生活水平都在提高&#xff0c;生活节奏也在逐渐加快。为了节省时间和提高工作效率&#xff0c;越来越多的人选择利用互联网进行线上打理各种事务&#xff0c;然后线上管理系统也就相继涌现。与此同时&#xff0c;人们开始接受方便的生活方式…

docker 不同架构镜像融合问题解决

1、背景 docker 作为目前容器的标准之一&#xff0c;但是对于多种架构的平台的混合编译支撑不是很好。因此衍生了镜像融合&#xff0c;分别将多种不同的架构构建好&#xff0c;然后将镜像进行融合上传。拉取镜像的会根据当前系统的架构拉取不同的镜像&#xff0c;也可以通过 -…

【mysql 127错误】mysql启动报错mysqld.service: Failed with result ‘exit-code‘.

无网环境&#xff0c;mysql 安装 出现如下错误 [rootmysql tools]# systemctl status mysqld.service ● mysqld.service - MySQL ServerLoaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)Active: failed (Result: exit-code) since…

Jupyter R绘图 汉字显示乱码的解决办法

1.Jupyte中&#xff0c;R绘图&#xff0c;汉字显示乱码 2.如何解决&#xff1f; (1)R中安装showtext 登录linux服务器 #R > install.packages(“showtext”) … 出错 (2)退出R,安装freetype-config #apt install libfreetype6-dev 出错 &#xff08;3&#xff09;进入R&…

vi\vim编辑器详解

vi\vim编辑器介绍 vi\vim是visual interface的简称, 是Linux中最经典的文本编辑器 同图形化界面中的 文本编辑器一样&#xff0c;vi是命令行下对文本文件进行编辑的绝佳选择。 vim 是 vi 的加强版本&#xff0c;兼容 vi 的所有指令&#xff0c;不仅能编辑文本&#xff0c;而…

Springboot+vue的四川美食分享网站+数据库+报告+免费远程调试

项目介绍: Springbootvue的四川美食分享网站。Javaee项目&#xff0c;springboot vue前后端分离项目 本文设计了一个基于Springbootvue的前后端分离的四川美食分享网站&#xff0c;采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&am…