JPA提供的save(S entity)可以实现更新,但是即使是null值,也会更新。不满足需求,所以对JPA的findById(Integer id)与save(S entity)进行封装,便可实现局部字段更新

核心:泛型方法和反射综合使用
1.封装局部更新工具类

package psn.kiko.util;import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;import java.lang.reflect.Field;/*** 利用泛型和反射封装的动态更新工具类* created by kiko on 2022-6-12*/
@Component
public class PartialUpdateUtil {/*** 根据主键id,实现JPA的动态更新** @param id  主键,一般为Integer类型* @param src 收集的用户数据* @param dao JpaRepository对象* @param <T> src对象对应的实体类型* @param <I> 主键参数对应的类型* @return 更新后的实体对象* @throws IllegalAccessException*/public <T, I> T partialUpdate(I id, T src, JpaRepository<T, I> dao) throws IllegalAccessException {T orig = dao.findById(id).get();T dest = src;Field[] fields = src.getClass().getDeclaredFields();for (Field field : fields) {if (!field.isAccessible()) {field.setAccessible(true);}//条件:对于某个Field,如果orig的值不为null,并且src的值为nullif (field.get(orig) != null&& field.get(src) == null) {//操作:则将orig的当前Field的值,赋值给dest对应的Fieldfield.set(dest, field.get(orig));}}T savedData = dao.save(dest);return savedData;}
}

2.测试示例

@SpringBootTest
public class UserRepositoryTest {@Autowiredprivate UserRepository dao;@Autowiredprivate PartialUpdateUtil updateUtil;@Testvoid dynamicUpdate() throws IllegalAccessException {User update = updateUtil.partialUpdate(1, new User(1, "testname2222", null), dao);System.out.println(update);}
}

单元测试结果:测试时模拟的password属性为null值,经过动态更新后,其值不变,仍然为数据库中原来的值,从而实现了:当用户传入null值的时候,数据库中与此对应的字段不更新为null值。

但从打印的SQL语句就可以发现并没有从根本上解决问题
update tb_user set password=?, uname=? where id=?
|_+
期待的SQL语句应该是(如果某个字段为null,则SQL直接不更新它),当password没有传值时,SQL应该长这样:
update tb_user set uname=? where id=?

Hibernate: select user0_.id as id1_0_0_, user0_.password as password2_0_0_, user0_.uname as uname3_0_0_ from tb_user user0_ where user0_.id=?
Hibernate: select user0_.id as id1_0_0_, user0_.password as password2_0_0_, user0_.uname as uname3_0_0_ from tb_user user0_ where user0_.id=?
Hibernate: update tb_user set password=?, uname=? where id=?
User(id=1, uname=testname2222, password=kkkkpass)

补充代码信息
3.实体类

package psn.kiko.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.*;@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "tb_user",schema = "hibernate")
public class User {@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id")private Integer id;@Column(name = "uname")private String uname;@Column(name = "password")private String password;
}

4.dao:并不直接提供动态更新的方法,局部更新需要用到一开始封装的工具类

package psn.kiko.dao;import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import psn.kiko.entity.User;import java.util.List;public interface UserRepository extends JpaRepository<User,Integer> {/*** 单个条件模糊查询* @param uname* @return*/List<User> findByUnameLike(String uname);/*** 多个条件进行模糊查询* @param uname* @param password* @return*/List<User> findByUnameLikeAndPasswordLike(String uname,String password);/*** 模糊查询* @param uname* @return*/List<User> findByUnameContains(String uname);/*** 单个条件分页* @param uname* @param pageable* @return*/List<User> findAllByUnameContains(String uname,Pageable pageable);/*** 多个条件分页* @param uname* @param password* @param pageable* @return*/List<User> findAllByUnameContainsAndAndPasswordContains(String uname,String password,Pageable pageable);
}

JPA只实现局部字段更新的解决办法(一)相关推荐

  1. Xamarin Android SDK无法更新的解决办法

    Xamarin Android SDK无法更新的解决办法 Xamarin Android SDK无法更新的解决办法,更新时候,提示警告信息:A folder failed to be moved.出现 ...

  2. Pycharm中无法导入各种Python模块,pip不能更新的解决办法

    一.Pycharm中无法导入各种Python模块,pip不能更新的解决办法 1.先用python -m pip uninstall pip 将之前版本的pip卸载 2.在官网上下载pip压缩包,记得下 ...

  3. antd 组件库upload使用时onChange只会执行到 uploading状态 解决办法

    antd 组件库使用时onChange只会执行到 uploading状态 解决办法 问题: 1.6.5版本 Upload控件onChange方法只会执行一次,且info.file.status一直为u ...

  4. windows10、windows11无法连接到打印机,错误代码0x0000011b,不删 KB5005565更新的解决办法,亲测可行

    windows10.windows11无法连接到打印机,错误代码0x0000011b,不删 KB5005565更新的解决办法,亲测可行共享打印机连接失败,提示错误代码0x0000011b此故障可能是由 ...

  5. QQ好友自定义头像不更新的解决办法(转)

    QQ好友自定义头像不更新的解决办法(转) 最近常有好友问QQ上的好友改了自定义头像后怎么更新不了.今天,笔者也遇到了同样的情况,在改了自定义头像后,好友列表中的自己的图像就是不能自动更新且更新好友资料 ...

  6. Windows10关机问题----只有“睡眠”、“更新并重启”、“更新并关机”,但是又不想更新,解决办法

    Windows10关机问题----只有"睡眠"."更新并重启"."更新并关机",但是又不想更新,解决办法 参考文章: (1)Windows1 ...

  7. Android Studio 自动更新失败解决办法

    Android Studio 自动更新失败解决办法 Dec 26th, 2014 | Comments 昨天在G+中看到Android Studio又有更新了就心血来潮想去更新体验一下,可是无论我怎么 ...

  8. IE缓存导致数据不能实时更新的解决办法

    查看全文 http://www.taodudu.cc/news/show-5902634.html 相关文章: IE缓存设置问题 清除IE缓存 关于IE缓存所带来的数据不能实时更新的解决办法 解决ie ...

  9. eset找不到服务器更新失败,eset nod32无法更新的解决办法-整理常见的nod32更新问题!...

    最近发现不少nod32爱好者朋友在使用nod32的过程中遇到nod32更新问题解决办法! 第一种:nod32更新提示不明严重错误(0x101a)造成的nod32无法更新 遇到这种问题我们首先要保持淡定 ...

最新文章

  1. 利用Unity3D制作简易2D计算器
  2. 跟我学Springboot开发后端管理系统2:Mybatis-Plus实战
  3. android gravity参数,Gravity - [ Android中文手册 ] - 在线原生手册 - php中文网
  4. Python3 SSH远程连接服务器
  5. zs040蓝牙模块使用方法_如何使用车载蓝牙播放手机音乐的方法
  6. FAIR 何恺明、Piotr、Ross等新作,MAE才是YYDS!仅用ImageNet1K,Top-1准确率87.8%!
  7. uban系统如何安装java_Ubuntu系统下安装Java并配置环境
  8. C++ tbb::atomic<bool> 声明、读取load、重新赋值store
  9. UITableView分段加载数据
  10. Android 角标设置
  11. 【SikuliX】基于图像识别的Web自动化测试
  12. 使用均匀分布验证中心极限定理)
  13. ERP实施顾问职业所具备的知识和能力结构的几个建议
  14. 【金融量化】我以为我是食物链顶层的收割者,想不到只是别人手中的镰刀
  15. AUTOSAR-基本概念
  16. 个人记账本,教你使用图表格查看项目
  17. Docker【部署 02】可视化工具DockerUI和Shipyard安装使用实例
  18. word07如何插入和删除分节符
  19. Linux 文本文件读取的七种方式
  20. 人工智能基础——推理的基本概念

热门文章

  1. 计算机思维试题简答题,六年级数学思维练习题及答案
  2. linux向文件追加行并求和
  3. tensorflow损失函数均方误差怎么计算
  4. dplyr包功能(数据清理、过滤、合并R实现)
  5. Python学习之生成动态二维码
  6. 实习在阿里(2015.07.09–2015.09.07)
  7. 光伏逆变器市场现状及未来发展趋势
  8. 新店开张,没有流量怎么办?
  9. npp夜光数据介绍 viirs_1.夜间灯光遥感数据概述
  10. 腾创网络始终专注于产品核心——互动视频会议组件