当前位置: 首页 > news >正文

优雅的Java:01.数据更新如何更优雅

在这里插入图片描述

编者按:如何写出更优雅的代码?这是一个恒久的问题,

在 Java 的世界里,SpringBoot 框架最为流程,几乎已经成为事实标准。本系列将围绕 SpringBoot 实战案例进行,介绍如何写出更优雅的 Java 代码。
笔者试图通过一个个的实际案例,抽丝剥茧,探讨 Spring 的设计哲学,探讨 Java 美学。

数据更新案例

数据更新的业务逻辑,很常见,举例例子,这里有一个更新发票信息的业务逻辑,按常规的思路,很容易写出这样的代码:

public function updateInvoice(UpdateInvoiceForm form) {Invoice updateInvoice = new Invoice();updateInvoice.setId(form.getId());// 更新发票号if(StringUtils.isNotBlank(form.getInvoiceTaxNumber())) {updateInvoice.setInvoiceTaxNumber(form.getInvoiceTaxNumber());}// 税额if(form.getTaxAmount() != null) {updateInvoice.setTaxAmount(form.getTaxAmount());}//  税前金额if(form.getTotalAmountPreTax() != null) {updateInvoice.setTotalAmountPreTax(form.getTotalAmountPreTax());}invoiceMapper.updateByPrimaryKeySelective(updateInvoice);
}

上面的逻辑也简单清晰,只有当某个上传的字段不为空时,才会更新数据库中相应的字段。那么,如果字段很多时,这样的代码就看起来非常冗余,那么,如何优化呢?

我们知道,Java 8 的 Optional 类,有着这样的用户:

  optionalVal.ifPresent(value -> xxx);

当前我们可以直接使用 Optional 类,将字段的更新逻辑封装在 Optional 类中,这样,代码就显得非常简洁,就像这样:

  Optional.ofNullable(form.getTaxAmount()).ifPresent(taxAmount -> {updateInvoice.setTaxAmount(taxAmount);})

不过这也有个问题,ifPresent 只支持判断对象是否为 null,无法过滤字符串为空的情况,基于这样的需要,我们可以仿照 Optional 类,自己实现一个封装

其核心代码像这样:

    public OptionalUtil<T> ifNotNull(Consumer<T> action) {if (value != null) {action.accept(value);}return this;}public OptionalUtil<T> ifNotBlank(Consumer<String> action) {if (value instanceof String && StringUtils.isNotBlank((String) value)) {action.accept((String) value);}return this;}

上面定义了两个核心方法,ifNotNull 和 ifNotBlank,分别用于判断对象是否为 null 和字符串是否为空,当满足条件时,再执行闭包里面的操作。

以下是完整的代码:

import java.util.function.Consumer;import org.apache.commons.lang3.StringUtils;public class OptionalUtil<T> {private final T value;private OptionalUtil(T value) {this.value = value;}public static <T> OptionalUtil<T> valueOf(T value) {return new OptionalUtil<>(value);}public OptionalUtil<T> ifBlank(Consumer<String> action) {if (value instanceof String && StringUtils.isBlank((String) value)) {action.accept((String) value);}return this;}public OptionalUtil<T> ifNotBlank(Consumer<String> action) {if (value instanceof String && StringUtils.isNotBlank((String) value)) {action.accept((String) value);}return this;}public OptionalUtil<T> ifNull(Consumer<T> action) {if (value == null) {action.accept(value);}return this;}public OptionalUtil<T> ifNotNull(Consumer<T> action) {if (value != null) {action.accept(value);}return this;}public OptionalUtil<T> ifZero(Consumer<T> action) {if (isZeroValue(value)) {action.accept(value);}return this;}private boolean isZeroValue(Object value) {if (value instanceof Number && ((Number) value).doubleValue() == 0.0d) {return true;}if (value instanceof java.util.Date && ((java.util.Date) value).getTime() <= 0) {return true;}return false;}public OptionalUtil<T> ifNotZero(Consumer<T> action) {if (!isZeroValue(value)) {action.accept(value);}return this;}public void execute() {// 可以用于触发链式调用的结束,也可以扩展为执行某些默认操作}
}

可以看到,这里面封装了一个 OptionalUtil 类,用于处理 Optional 类的链式调用。里面包括一个静态构造方法 valueOf, 同时支持各类不同的类型,
不论是 String,还是继承 Number 的类,如 Integer,Long,BigDecimal 等,进行判断。

时间 ifZero 也支持时间类型,如果传的时间为 1970-01-01 00:00:00 及以前的时间,也视做零值。

这样,我们的更新代码就可以写成这样:

public function updateInvoice(UpdateInvoiceForm form) {Invoice updateInvoice = new Invoice();updateInvoice.setId(form.getId());// 更新发票号OptionalUtil.valueOf(form.getInvoiceTaxNumber()).ifNotBlank(updateInvoice::setInvoiceTaxNumber);// 税额OptionalUtil.valueOf(form.getTaxPreAmount()).ifNotBlank(updateInvoice::setTaxPreAmount);//  税前金额OptionalUtil.valueOf(form.getTotalAmountPreTax()).ifNotBlank(updateInvoice::setTotalAmountPreTax);invoiceMapper.updateByPrimaryKeySelective(updateInvoice);
}

这样,优雅的数据更新就实现了,你觉得怎么样呢,欢迎在评论区交流。

http://www.lryc.cn/news/588890.html

相关文章:

  • 2025开放原子开源生态大会 | openKylin的技术跃迁和全球协作
  • 2025阿里云黑洞恢复全指南:从应急响应到长效防御的实战方案
  • CentOS服务器安装Supervisor使队列可以在后台运行
  • 2.3 数组与字符串
  • QGIS新手教程9:字段计算器进阶用法与批量处理技巧
  • HTTP性能优化实战技术
  • 串口通信性能优化
  • golang语法-----变量、常量
  • Go语言统计字符串中每个字符出现的次数 — 简易频率分析器
  • 解锁Redis:从安装到配置的全攻略
  • DBeaver 传输数据库A数据到数据库B
  • LLM指纹底层技术——特征提取
  • 06-C语言:第06天笔记
  • python的广东省家庭旅游接待信息管理系统
  • 文心一言4.5开源模型测评:ERNIE-4.5-0.3B超轻量模型部署指南
  • NineData 社区版 V4.3.0 正式发布!新增 5 条迁移对比链路,全面支持 MariaDB、GaussDB 等数据库
  • 使用python的pillow模块将图片转化为灰度图,获取值和修改值
  • Redis Desktop Manager(RDM)下载与安装使用教程
  • STM32小实验二--流水灯
  • 【R语言】警告conversion failure on ‘中文字符‘ in ‘mbcsToSbcs‘: for 注 (U+6CE8)
  • 海狸IM - 一个功能完整的开源即时通讯系统
  • DeepSWE:通过强化学习扩展训练开源编码智能体
  • 2025开放原子开源生态大会 | 开源欧拉的AI原生实践与全球协作
  • 基于开源AI大模型、AI智能名片与S2B2C商城小程序源码的用户价值引导与核心用户沉淀策略研究
  • Android target34升级到35中的edge-to-edge适配
  • 【Android】按钮的使用
  • Softhub软件下载站实战开发(十八):软件分类展示
  • 图像修复:深度学习实现老照片划痕修复+老照片上色
  • 三种深度学习模型(LSTM、CNN-LSTM、贝叶斯优化的CNN-LSTM/BO-CNN-LSTM)对北半球光伏数据进行时间序列预测
  • Datawhale AI 夏令营第一期(机器学习方向)Task2 笔记:用户新增预测挑战赛 —— 从业务理解到技术实现