解决springjpa的局部更新字段问题

问题描述:

使用springjpa更新数据时,有时候我们需要更新部分字段,对已有的内容保持不变,通常我们可以通过Spring提供的bean工具类BeanUtils来实现

解决方法:

BeanUtils复制对象,BeanUtils中的构造方法属性中可以通过传入更新时忽略的属性值来实现选择性复制原对象的字段。更新部分字段时,我们仅需要传入复制后的字段即可。

解析和实现:

BeanUtils的构造方法:

具体更新部分字段的步骤:

查询出待更新对象的原有信息

通过传入的更新的象去复制产生一个新对象,其中新对象中为null的字段不需要更新。

执行更新操作,操作对象时步骤2得出的复制对象。

代码如下:

public Result update(@RequestBody AppScene appScene, @PathVariable String id ){
 AppScene target = appSceneService.findById(id); //数据库查出待更新对象
 BeanUtils.copyProperties(appScene,target,getNullPropertyNames(appScene)); //使用更新对象的非空值去覆盖待更新对象
 appSceneService.update(target ); //执行更新操作
 return new Result(true,StatusCode.OK,"修改成功");
}

其中涉及的getNullPropertyNames方法作为工具类存在,具体如下:

public static String[] getNullPropertyNames (Object source) {
 final BeanWrapper src = new BeanWrapperImpl(source);
 java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
 Set<String> emptyNames = new HashSet<String>();
 for(java.beans.PropertyDescriptor pd : pds) {
 Object srcValue = src.getPropertyValue(pd.getName());
 if (srcValue == null) emptyNames.add(pd.getName());
 }
 String[] result = new String[emptyNames.size()];
 return emptyNames.toArray(result);
 }

更新:

这是之前刚开始学习框架的时候遇到的问题,其实这个问题spring早就提供了对应的方法去解决,它提供了对应bean拷贝的方法BeanUtils.copyProperties,通过传入不同的值决定是否要忽略非空属性值的拷贝,现在已经没有必要自己手写了。

补充:Java Jpa选择性更新、部分字段更新工具类

使用Jpa自带的Save方法更新实体类时,会覆盖数据库中实体类原有内容。如果我们只想更新一部分字段或是选择性的更新,就只能另辟蹊径了。

这个工具类很好地弥补了这个不足,对于待更新实体类中有内容的字段会更新,为空的字段会采用原数据库中内容,下面是工具类代码(附使用方法)。

工具类代码:

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.util.HashSet;
import java.util.Set;
/**
 * jpa 部分字段更新方法
 */
public class UpdateColumnUtil {
 public static String[] getNullPropertyNames(Object source) {
  final BeanWrapper src = new BeanWrapperImpl(source);
  java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
  Set<String> emptyNames = new HashSet<>();
  for (java.beans.PropertyDescriptor pd : pds) {
   Object srcValue = src.getPropertyValue(pd.getName());
   if (srcValue == null) emptyNames.add(pd.getName());
  }
  String[] result = new String[emptyNames.size()];
  return emptyNames.toArray(result);
 }
}

使用方法:

//首先从数据库查出待更新对象
Customer target = customerService.findById(customer.getCustId());
//使用更新对象的非空值去覆盖待更新对象
BeanUtils.copyProperties(customer, target, UpdateColumnUtil.getNullPropertyNames(customer));
//执行更新操作
save = customerService.save(target);

这样一个映射就完成我们的需求了。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • 解决springboot无法注入JpaRepository的问题

    使用内置服务器启动springboot项目时,会从@SpringBootApplication修饰类所在的包开始,加载当前包和所有子包下的类,将由@Component @Repository @Service @Controller修饰的类交由spring进行管理. package com.facade; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure

  • springboot 之jpa高级查询操作

    springboot的jpa可以根据方法名自动解析sql 非常方便, 只需要在 dao接口中定义方法即可; 下面是一个 demo package com.bus365.root.dao; import java.io.Serializable; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.reposi

  • SpringBoot2 实现JPA分页和排序分页的案例

    分页 application.yml spring: datasource: url: jdbc:mysql://127.0.0.1/jpa?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver jpa: hibernate: # 更新或者创建数据表结构 ddl-auto: update # 控

  • SpringBoot2 Jpa 批量删除功能的实现

    前台处理 首先前台先要获取所有的要删除数据的ID,并将ID拼接成字符串 例如: 2,3,4,5,然后通过GET请求返送到后台. 后台处理 控制器接收 /** * @function 批量删除 * @param stu_id * @return */ @GetMapping("/del_stu") @ResponseBody public Msg batch_del_stu(@RequestParam("stu_id") String stu_id){ // 接收包含

  • springdata jpa单表操作crud的实例代码详解

    1. 项目搭建 使用boot整合,导入springdata jap, mysql 驱动,lombok,web. 1.1 配置 # boot add jpa, oh~ crud in single table server: port: 8888 spring: # datasource datasource: username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://

  • SpringBoot2 JPA解决懒加载异常的问题

    jpa解决懒加载异常 在我上一遍文章上进行行修改,SpringBoot2 实现JPA分页和排序分页 实体类上改: @Entity @Table(name = "employee") @JsonIgnoreProperties(value={"hibernateLazyInitializer", "department"}) public class Employee { @Id @GeneratedValue(strategy = Generat

  • 基于springboot2集成jpa,创建dao的案例

    springboot中集成jpa需要再pom文件中添加jpa的jar包,使用springboot的话iju不用自己规定版本号了,自动管理依赖版本即可. <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> 然后我们再添加hibernate和o

  • 解决springjpa的局部更新字段问题

    问题描述: 使用springjpa更新数据时,有时候我们需要更新部分字段,对已有的内容保持不变,通常我们可以通过Spring提供的bean工具类BeanUtils来实现 解决方法: BeanUtils复制对象,BeanUtils中的构造方法属性中可以通过传入更新时忽略的属性值来实现选择性复制原对象的字段.更新部分字段时,我们仅需要传入复制后的字段即可. 解析和实现: BeanUtils的构造方法: 具体更新部分字段的步骤: 查询出待更新对象的原有信息 通过传入的更新的象去复制产生一个新对象,其中

  • 解决mybatis update并非所有字段需要更新问题

    目录 mybatis update并非所有字段需要更新 解决办法 mybatis update时遇到的问题 mybatis update并非所有字段需要更新 mybatis update 需求:更新字段作为参数,未更新字段不传入 解决办法 <update id="updateUser" parameterType="com.test.entity.User"> update BS_USER <trim prefix="set"

  • 解决Swagger修改请求对象字段文档不更新问题

    目录 解决方法 描述 解决方法 有两个对象用了同一个@ApiModel的value值 描述 今天发现不管怎么修改如下对象,接口显示总是不变 @Data @NoArgsConstructor @AllArgsConstructor @ApiModel(value = "账单查询对象",description = "请求参数类") public class QueryBillVO { @ApiModelProperty(value = "页码",ex

  • 详解WebApiClient的JsonPatch局部更新

    1. 文章目的 随着 WebApiClient的不断完善,越来越多开发者选择WebApiClient替换原生的HttpClient,本文将介绍使用WebApiClient来完成JsonPatch提交的新特性. 2. json patch介绍 在服务端WebApi开发的时候,如果设计一个更新登录用户的个人信息的接口,用户能更新昵称.密码.生日.性别等N多个字段,但用户在实际使用中,可能是更新其中的一个或不确定多个字段.开发者往往会为难:对于客户端没有更新到的字段,应该设置为什么值呢?一种是让客户端

  • 使用Ajax局部更新Razor页面的实例代码

    Razor功能非常强大,但是本身并不能做到无刷新,所以需要配合ajax使用 本文就做一个简单例子,实现Razor配合ajax做到局部刷新. 首先,我们创建一个MVC项目 让我们创建一个简单的Controller Book 然后对其添加一个视图,并且添加上一些简单的Html代码 @{ ViewBag.Title = "Index"; Layout = null; } <!DOCTYPE html> <html> <head> <meta http

  • Mysql两种情况下更新字段中部分数据的方法

    Mysql更新字段中部分数据第一种情况:  复制代码 代码如下: update tab set A = concat(substring(A,1,3),'bbb'); 从A的1个字符开始取3个字符,加上'bbb',再写入a中,如果A原始值为'123aaa',那么更新之后为'123bbb'了. 如果我们要将字段A值中的包含的1,替换成2呢? 例如:a=2211,现在要替换成2222,就是把1换成2 SQl语句这么写: 复制代码 代码如下: update table set a=REPLACE(a,

  • SSH框架网上商城项目第28战之使用Ajax技术局部更新商品数量和总价

    之前,把项目部署了一下,玩了玩,今天完善了一下购物车中修改商品数量就能局部更新相应的总价的功能,大家都知道这得用Ajax实现,我之前也没学Ajax,刚好借助这个小功能,去简单学习一下Ajax的知识. 1. 问题的分析 先看一下页面中的情况: 功能如上,在没有Ajax之前,一般都是根据用户修改的值去找Action,然后返回新的jsp页面重新加载整个页面,完成数字的更新.但是有了Ajax技术后,我们可以利用Ajax技术局部刷新要改变的地方,而不是重新加载整个页面.首先看一下上图对应的jsp部分的代码

  • .Net页面局部更新引发的思考

    最近在修改以前做的模块,添加一个新功能.整理了下才发现重用率很低,大部分的东西还是需要重新写.功能里用到了局部更新,所有整理一下一路来实现局部更新的解决方案及改进. 我接触的项目开发大多是以Asp.net WebForm开发的,自然会用到UpdatePanel,好处就是开发快.方便,当然产生的问题也是一大堆.然后是Ajax和一般处理程序配合实现异步请求更新.最后就是利用第三方绑定插件优化Ajax请求.  一.UpdatePanel  将需要更新的模块放入UpdatePanel的ContentTe

  • 解决mybatis使用char类型字段查询oracle数据库时结果返回null问题

    同事在学mybatis时,遇到了一个问题就是,使用char类型字段作为查询条件时一直都查不出数据,其他类型的则可以. 使用的数据库是oracle,查询条件字段类型是char(50),java代码对应的是String类型. 后来经过排查,是由于在oracle中,char类型字段,如果内容长度不够,会自动以空格方式补足长度.如字段 name char(5),若值为sgl,那么oracle会自动用空格补足长度,最终值为sgl. 一.解决方法: 方法1:先用trim()函数把值去掉两边空格再作为条件查询

  • 解决vuecli3.0热更新失效的问题

    webpack的热更新可以说极大地提高了前端的开发效率,以下就是本人遇到的针对vuecli热更新失效的解决方法: 1.检查控制台,编译的时候是否有警告,警告很可能导致热更新的失效 2.vueCli3.0及以上的版本,注意不要用cnpm安装依赖包,要用npm 以上这篇解决vuecli3.0热更新失效的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

随机推荐