原创
JPA不更新值为null的解决方案&&JPA优雅的更新
关于@DynamicUpdate
注解
使用@DynamicUpdate注解,通过在Entity实体类上添加此注解,再结合repository.save()方法进行字段更新,此方法的确具有可行性,但是仍存在一个问题:当字段值为null值时,Jpa会将null值与原值作比较,如果原值不为null,那么原值将会被覆盖为null
解决办法 - JpaUtil
写一个JpaUtil
工具类避免空值对于动态部分更新的影响,配合@DynamicUpdate
一起使用。
核心就是使用的Spring的BeanUtils
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapperImpl;
import java.beans.PropertyDescriptor;
import java.util.stream.Stream;
/**
* JPA避免一些空值对于动态部分更新的影响工具类
*
* @author Zhaopo Liu
*/
public class JpaUtil {
/**
* 查询出entity值 -> JpaUtil.copyNotNullProperties(input, entity); -> save(entity)
*
* @param input 输入实体类
* @param entity 数据库查询出的实体类
*/
public static void copyNotNullProperties(Object input, Object entity) {
BeanUtils.copyProperties(input, entity, getNullPropertyNames(input));
}
/**
* 忽略的字段:值为null、浮点数为0.0、值为空字符串""
*
* ignoreProperties {@link BeanUtils#copyProperties(java.lang.Object, java.lang.Object, java.lang.String...)}
*
* @param object 传入全部字段
* @return 忽略的字段
*/
private static String[] getNullPropertyNames(Object object) {
final BeanWrapperImpl wrapper = new BeanWrapperImpl(object);
return Stream.of(wrapper.getPropertyDescriptors()).map(PropertyDescriptor::getName)
.filter(propertyName -> wrapper.getPropertyValue(propertyName) == null
|| "0.0".equals(String.valueOf(wrapper.getPropertyValue(propertyName)))
|| "".equals(String.valueOf(wrapper.getPropertyValue(propertyName))))
.toArray(String[]::new);
}
}
使用demo:
这种方式比较优雅,避免了你写很多setXXX(...),省去了很多代码,让你的代码更具有可读性。
@Transactional(rollbackFor = Exception.class)
public IronFastenersInsulationTask createOrUpdate(IronFastenersInsulationTask insulationTask) {
return Optional.of(ironFastenersInsulationTaskRepository.findByIdOrTaskId(insulationTask.getTaskId())
.orElseGet(() -> ironFastenersInsulationTaskRepository.save(insulationTask))).map(entity -> {
// 使用JpaUtil优雅的写法
JpaUtil.copyNotNullProperties(insulationTask, entity);
// 不优雅的写法
// entity.setRemark(insulationTask.getRemark());
// entity.setTestTemperature(insulationTask.getTestTemperature());
// entity.setHumidity(insulationTask.getHumidity());
// entity.setTestDeviceName(insulationTask.getTestDeviceName());
// entity.setIronGround(insulationTask.getIronGround());
// entity.setClipGround(insulationTask.getClipGround());
// entity.setIronClip(insulationTask.getIronClip());
// return ironFastenersInsulationTaskRepository.save(entity);
return ironFastenersInsulationTaskRepository.save(entity);
}).orElseGet(() -> ironFastenersInsulationTaskRepository.save(insulationTask));
}
核心就是使用Spring的BeanUtils
的copyProperties
方法,里面有一个ignoreProperties
是指忽略拷贝的字段:
public static void copyProperties(Object source, Object target, String... ignoreProperties) throws BeansException {
copyProperties(source, target, (Class)null, ignoreProperties);
}
- 本文作者: lzhpo
- 本文链接: http://www.lzhpo.com/article/163
- 版权声明: 本文为本人原创文章,采用 CC BY 3.0 CN协议 ,可自由转载、引用,但需署名作者且注明文章出处。
正文到此结束