9

JPA不更新值为null的解决方案&&JPA优雅的更新

 3 years ago
source link: http://www.lzhpo.com/article/163
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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的BeanUtilscopyProperties方法,里面有一个ignoreProperties是指忽略拷贝的字段:

public static void copyProperties(Object source, Object target, String... ignoreProperties) throws BeansException {    copyProperties(source, target, (Class)null, ignoreProperties);}
正文到此结束
所属分类:Java开发

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK