JPA只实现局部字段更新的解决办法(一)
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只实现局部字段更新的解决办法(一)相关推荐
- Xamarin Android SDK无法更新的解决办法
Xamarin Android SDK无法更新的解决办法 Xamarin Android SDK无法更新的解决办法,更新时候,提示警告信息:A folder failed to be moved.出现 ...
- Pycharm中无法导入各种Python模块,pip不能更新的解决办法
一.Pycharm中无法导入各种Python模块,pip不能更新的解决办法 1.先用python -m pip uninstall pip 将之前版本的pip卸载 2.在官网上下载pip压缩包,记得下 ...
- antd 组件库upload使用时onChange只会执行到 uploading状态 解决办法
antd 组件库使用时onChange只会执行到 uploading状态 解决办法 问题: 1.6.5版本 Upload控件onChange方法只会执行一次,且info.file.status一直为u ...
- windows10、windows11无法连接到打印机,错误代码0x0000011b,不删 KB5005565更新的解决办法,亲测可行
windows10.windows11无法连接到打印机,错误代码0x0000011b,不删 KB5005565更新的解决办法,亲测可行共享打印机连接失败,提示错误代码0x0000011b此故障可能是由 ...
- QQ好友自定义头像不更新的解决办法(转)
QQ好友自定义头像不更新的解决办法(转) 最近常有好友问QQ上的好友改了自定义头像后怎么更新不了.今天,笔者也遇到了同样的情况,在改了自定义头像后,好友列表中的自己的图像就是不能自动更新且更新好友资料 ...
- Windows10关机问题----只有“睡眠”、“更新并重启”、“更新并关机”,但是又不想更新,解决办法
Windows10关机问题----只有"睡眠"."更新并重启"."更新并关机",但是又不想更新,解决办法 参考文章: (1)Windows1 ...
- Android Studio 自动更新失败解决办法
Android Studio 自动更新失败解决办法 Dec 26th, 2014 | Comments 昨天在G+中看到Android Studio又有更新了就心血来潮想去更新体验一下,可是无论我怎么 ...
- IE缓存导致数据不能实时更新的解决办法
查看全文 http://www.taodudu.cc/news/show-5902634.html 相关文章: IE缓存设置问题 清除IE缓存 关于IE缓存所带来的数据不能实时更新的解决办法 解决ie ...
- eset找不到服务器更新失败,eset nod32无法更新的解决办法-整理常见的nod32更新问题!...
最近发现不少nod32爱好者朋友在使用nod32的过程中遇到nod32更新问题解决办法! 第一种:nod32更新提示不明严重错误(0x101a)造成的nod32无法更新 遇到这种问题我们首先要保持淡定 ...
最新文章
- 利用Unity3D制作简易2D计算器
- 跟我学Springboot开发后端管理系统2:Mybatis-Plus实战
- android gravity参数,Gravity - [ Android中文手册 ] - 在线原生手册 - php中文网
- Python3 SSH远程连接服务器
- zs040蓝牙模块使用方法_如何使用车载蓝牙播放手机音乐的方法
- FAIR 何恺明、Piotr、Ross等新作,MAE才是YYDS!仅用ImageNet1K,Top-1准确率87.8%!
- uban系统如何安装java_Ubuntu系统下安装Java并配置环境
- C++ tbb::atomic<bool> 声明、读取load、重新赋值store
- UITableView分段加载数据
- Android 角标设置
- 【SikuliX】基于图像识别的Web自动化测试
- 使用均匀分布验证中心极限定理)
- ERP实施顾问职业所具备的知识和能力结构的几个建议
- 【金融量化】我以为我是食物链顶层的收割者,想不到只是别人手中的镰刀
- AUTOSAR-基本概念
- 个人记账本,教你使用图表格查看项目
- Docker【部署 02】可视化工具DockerUI和Shipyard安装使用实例
- word07如何插入和删除分节符
- Linux 文本文件读取的七种方式
- 人工智能基础——推理的基本概念