后端开发必知:BeanUtils 如何在 DTO 与 VO 间巧妙复制数据

news/2024/10/21 14:22:52/

作为一名后端开发者,我们深知数据安全的重要性,尤其是像手机号、身份证号等关键数据

为了防止关键数据泄露,JAVA领域,基本都采用了 VO(Value Object)和 DTO(Data Transfer Object)的模式,VO(Value Object)通常只会回传最关键的属性,而DTO(Data Transfer Object)一般则包含表的所有字段数据。因此,DTO和VO之间通常需要进行关键字段的数据复制。今天,我们就来分享一个工具类——BeanUtils,并剖析其数据复制的源码。

一、BeanUtils工具类

BeanUtils是Spring框架提供的用于处理JavaBean的静态工具方法类,如实例化bean、检查bean属性类型、复制bean属性等。

1. 核心方法

  • instantiateClass(Class clazz):根据给定的类创建一个新的实例。
  • copyProperties(Object source, Object target, String… ignoreProperties):将一个对象的属性值复制到另一个对象中,可以指定忽略的属性。
  • findPropertyType(String propertyName, @Nullable Class<?>… beanClasses):获取指定Bean属性的类型。

2. 数据复制场景

想象一下这样的场景:我们从数据库中获取了完整的用户数据,存储在 DTO 中。但是,当我们要将这些数据展示给前端页面时,我们并不希望将所有的字段都暴露出去,只需要传递一些关键的信息。这时,我们就可以利用 BeanUtils 工具类,将 DTO 中这些关键的属性复制到 VO 中,然后将 VO 传递给前端。这样,既保证了数据的安全性,又提高了数据传输的效率

二、copyProperties方法分析

copyProperties方法的核心可总结为两步。

  1. 获取目标对象及其getter和setter方法
java">Class<?> actualEditable = target.getClass();
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
  1. 遍历目标对象的所有属性,并通过反射机制从源对象中获取对应属性的值,最后赋值给目标对象
java">for (PropertyDescriptor targetPd : targetPds) {Method writeMethod = targetPd.getWriteMethod();// 确保write方法存在if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());if (sourcePd != null) {Method readMethod = sourcePd.getReadMethod();// 确保read方法存在if (readMethod != null &&ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {try {// 设置读方法的可访问性if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {readMethod.setAccessible(true);}// 获取source类对应属性的值Object value = readMethod.invoke(source);// 设置写方法的可访问性if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {writeMethod.setAccessible(true);}// 赋值writeMethod.invoke(target, value);}catch (Throwable ex) {throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", ex);}}}}}

通过上述步骤,copyProperties方法能够有效地实现对象间属性值的复制,同时支持忽略指定属性,从而满足不同场景下的需求。

三、总结

BeanUtils类的copyProperties方法,在保证数据安全的前提下,高效地实现了 DTO 和 VO 之间的数据复制。在实际开发中,我们要充分理解和掌握它的原理和使用方法,同时注意可能出现的问题,如属性名称匹配、类型兼容性((《MyBatis 数据表与实体映射的隐藏陷阱》))和性能优化等


http://www.ppmy.cn/news/1539179.html

相关文章

数据分布过于集中 怎么办,python 人工智能 ,数据分析,机器学习pytorch tensorflow ,

数据分布过于集中&#xff0c;意味着数据的大部分值都聚集在某个特定区间内&#xff0c;这可能会导致统计分析的结果不够稳健&#xff0c;或者模型训练时出现过拟合等问题。针对这种情况&#xff0c;可以考虑以下几种方法来处理&#xff1a; 变换成 1. **数据转换**&#xff1…

Leetcode 2466. 统计构造好字符串的方案数 入门dp(取模) C++实现

问题&#xff1a;Leetcode 2466. 统计构造好字符串的方案数 给你整数 zero &#xff0c;one &#xff0c;low 和 high &#xff0c;我们从空字符串开始构造一个字符串&#xff0c;每一步执行下面操作中的一种&#xff1a; 将 0 在字符串末尾添加 zero 次。将 1 在字符串末尾添…

GaussDB 主备版本8 -数据库对象 学习

1 表空间 1.1 GaussDB自带了两个表空间&#xff1a;pg_default和pg_global 1.1.1 默认表空间pg_default&#xff1a;用来存储非共享系统表、用户表、用户表index、临时表、临时表index、内部临时表的默认表空间。对应存储目录为实例数据目录下的base目录。 1.1.2 共享表空间pg…

Java 多线程(一)—— 线程的创建与属性

线程的创建 方式一&#xff1a;继承 Thread 类&#xff0c;重写 run 方法 class MyThread extends Thread {Overridepublic void run() {System.out.println("hello Thread");} }方式二&#xff1a;实现 Runnnable 接口&#xff1a; class MyRunnable implements …

探索 MicroRabbit:Python 中的通信新纪元

文章目录 探索 MicroRabbit&#xff1a;Python 中的通信新纪元背景&#xff1a;为什么选择 MicroRabbit&#xff1f;MicroRabbit 是什么&#xff1f;如何安装 MicroRabbit&#xff1f;简单的库函数使用方法场景应用示例常见 Bug 及解决方案总结 探索 MicroRabbit&#xff1a;Py…

Git客户端使用之TortoiseGit和Git

git客户端有两个分别是TortoiseGit和Git Git用于命令行TortoiseGit用于图形界面。无论是Git还是TortoisGit都需要生成公/私钥与github/gitlab建立加密才能使用。 一、先介绍Git的安装与使用 1、下载与安装 安装Git-2.21.0-64-bit.exe(去官网下载最新版64位的)&#xff0c;安…

YUV视频数据类型

YUV视频数据类型 1. 概述2. YUV420P2.1 YU122.2 YV123. YUV420SP3.1 NV213.2 NV124. YUV 和 RGB 转换1. 概述 YUV 视频数据是根据一个亮度 Y 和两个色度 UV 来定义的颜色空间。常见的 YUV 格式有 I420,NV12,YV12。 YUV 有三种采样模式,其中: YUV 4:4:4 采样,每一个 Y 对…

洗衣店订单管理:Spring Boot技术实现

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常适…