springdataJPA更新操作如何防止丟失數(shù)據(jù)

當(dāng)用springdatajpa自帶save()進(jìn)行更新操作時(shí),會先在底層執(zhí)行merge()的一個(gè)動作,而執(zhí)行merge動作時(shí)根據(jù)entiy標(biāo)簽里面的@ID,也就是主鍵來區(qū)分的,所以正確的更新方式是先把對應(yīng)的entiy查詢出來,然后在更新某個(gè)字段。
這就引申出一個(gè)問題,假如我們直接使用實(shí)體對象來接收更新參數(shù),所以我們并不知道哪個(gè)字段被更改掉。這就涉及到新老數(shù)據(jù)的對比操作。雖然我們可以直接使用BeanUtils.copyProperties(oldEntiy,newEntiy);來進(jìn)行數(shù)據(jù)拷貝,但在不注意情況下就會出現(xiàn)丟失數(shù)據(jù)的情況。
如何防止這種情況呢。這里可以運(yùn)用java的反射機(jī)制來處理這種情況。話不多說,直接上代碼:

import java.beans.IntrospectionException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author lqyang
 * @Title: SPRING-JPA-DATA 更新操作時(shí) 校驗(yàn)數(shù)據(jù)是否為空 解決處理BeanUtils.copyProperties(obj1,obj2);為空數(shù)據(jù)的處理
 * @date 2018/8/217:00
 */
public class FieldUtil<T> {

    private T  entity;

    public FieldUtil(T entity){
        this.entity = entity;
    }

    /**
     * 使用案例:
     *   SysUserEntity sysUserEntity = sysUserDao.findOne(user.getUserId());
     *      BeanUtils.copyProperties(sysUserEntity,user);
     *      if(sysUserEntity != null){
     *      for(Field f : user.getClass().getDeclaredFields()){
     *          f.setAccessible(true);
     *              if(f.get(user) == null){
     *              String name = f.getName();
     *              FieldUtil<SysUserEntity> fieldUtil = new FieldUtil<>(user);
     *              fieldUtil.doInitEntity(name,sysUserEntity);
     *      }
     *  }
     *      sysUserDao.save(user);
     *  }else {
     *      user.setUserId(StringUtil.uuid());
     *  sysUserDao.save(user);
     *  }
     * @param methodName
     * @param object
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws NoSuchFieldException
     * @throws IntrospectionException
     */
    public  void doInitEntity(String methodName,Object object) throws InvocationTargetException, IllegalAccessException, NoSuchFieldException, IntrospectionException {
        //根據(jù)傳入的屬性名稱構(gòu)造屬性的set方法名
        String str = methodName.substring(0, 1).toUpperCase()+methodName.substring(1);
        String methodNameNew = "set"+str;
        Method[] methods = entity.getClass().getMethods();
        for(Method method:methods){
            //如果方法同名則執(zhí)行該方法(不能用于實(shí)體中有重載方法的情況)
            if(methodNameNew.equals(method.getName())){
                Class<?>[] clazz = method.getParameterTypes();
                String type = clazz[0].getName();
                if(type.equalsIgnoreCase("java.lang.String")){
                    Field field = object.getClass().getDeclaredField(methodName);
                    field.setAccessible(true);
                    if(field.get(object) != null){
                        method.invoke(entity,(String)field.get(object));
                    }
                }
                else if(type.equalsIgnoreCase("java.util.Date")){
                    Field field = object.getClass().getDeclaredField(methodName);
                    field.setAccessible(true);
                    if(field.get(object) != null){
                        method.invoke(entity, (Date)field.get(object));
                    }
                }
                else if(type.equalsIgnoreCase("java.lang.Integer")){
                    Field field = object.getClass().getDeclaredField(methodName);
                    field.setAccessible(true);
                    if(field.get(object) != null){
                        method.invoke(entity, new Integer((Integer) field.get(object)));
                    }
                }
                else if(type.equalsIgnoreCase("java.lang.Float")){
                    Field field = object.getClass().getDeclaredField(methodName);
                    field.setAccessible(true);
                    if(field.get(object) != null){
                        method.invoke(entity, new Float((Float) field.get(object)));
                    }
                }
                else if(type.equalsIgnoreCase("java.lang.Boolean")){
                    Field field = object.getClass().getDeclaredField(methodName);
                    field.setAccessible(true);
                    if(field.get(object) != null){
                        method.invoke(entity, new Boolean((Boolean) field.get(object)));
                    }
                }
                else if(type.equalsIgnoreCase("java.math.BigDecimal")){
                    Field field = object.getClass().getDeclaredField(methodName);
                    field.setAccessible(true);
                    if(field.get(object) != null){
                        method.invoke(entity, (BigDecimal) field.get(object));
                    }
                }
            }
        }
    }
}

使用案例

@Transactional(rollbackFor = Exception.class)
    public void updateUser(SysUserEntity user)throws Exception {
        SysUserEntity sysUserEntity = sysUserDao.findOne(user.getUserId());
        //BeanUtils.copyProperties(sysUserEntity,user);
        if(sysUserEntity != null){
            for(Field f : user.getClass().getDeclaredFields()){
                f.setAccessible(true);
                if(f.get(user) == null){
                    String name = f.getName();
                    FieldUtil<SysUserEntity> fieldUtil = new FieldUtil<>(user);
                    fieldUtil.doInitEntity(name,sysUserEntity);
                }
            }
            sysUserDao.save(user);
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容