在使用jpa进行操作数据库时,我们经常会遇到更新数据问题。jpa的save方法可以解决这个问题,但这个方法有一个局限,在匹配到相同主键的记录是可以进行更新,但是会将传入参数的值全部更新到数据库中。 例如下面两个对象
数据库:
demo{
id:1,
name:one,
number:123
info:yes
}
传入参数:
demo2{
id:1,
name:two,
number:null
info:null
}
在上面这种情况下,你的目的可能只是更新某个值,例如只修改name在数据库的存储值,并不修改其他的值,如下图所示:
但是jpa的save默认会将demo2的值直接覆盖数据库中demo的值,此时number和info的值也会修改,结果如下图
为了实现部分更新可以采用在实体类上标注@DynamicUpdate 和配合BeanUtils的方式
实现复制非空属性值的工具类
package com.example.demo.Utils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.beans.PropertyDescriptor;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;
public class JpaUtil {
public static void copyNotNullProperties(Object src,Object target){
BeanUtils.copyProperties(src,target,getNullPropertyNames(src));
}
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);
}
}
实体类
package com.example.demo.entities;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.*;
import lombok.experimental.Accessors;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.*;
import java.io.Serializable;
/**
* @author xiaow
*/
@Entity
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Data
@Table(name="apply")
@Accessors(chain = true)
@JsonIgnoreProperties(value = { "hibernateLazyInitializer"})
@DynamicUpdate //动态更新
public class Apply implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Integer state;
private Integer studentid;
private Integer awardtype;
private String info;
private String name;
private Integer type;
private Integer teacherid;
private Integer teacherstate;
}
持久层
public interface ApplyRepos extends JpaRepository<Apply,Integer> {}
事务实现层
public int updateAll(Apply apply) {
int a=0;
if(apply!=null&&apply.getId() != null) {
Apply apply1 = applyRepos.getOne(apply.getId());
if (apply1!=null) {
//将apply中非空的值赋给apply1中,并将apply1重新存储
JpaUtil.copyNotNullProperties(apply, apply1);
}
a=applyRepos.save(apply1).getId();
}
return a;
}
这样就实现了jpa的动态更新记录
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有