美文网首页
springdataJPA更新操作如何防止丢失数据

springdataJPA更新操作如何防止丢失数据

作者: 杨少侠_Y | 来源:发表于2018-09-05 10:33 被阅读0次

当用springdatajpa自带save()进行更新操作时,会先在底层执行merge()的一个动作,而执行merge动作时根据entiy标签里面的@ID,也就是主键来区分的,所以正确的更新方式是先把对应的entiy查询出来,然后在更新某个字段。
这就引申出一个问题,假如我们直接使用实体对象来接收更新参数,所以我们并不知道哪个字段被更改掉。这就涉及到新老数据的对比操作。虽然我们可以直接使用BeanUtils.copyProperties(oldEntiy,newEntiy);来进行数据拷贝,但在不注意情况下就会出现丢失数据的情况。
如何防止这种情况呢。这里可以运用java的反射机制来处理这种情况。话不多说,直接上代码:

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 更新操作时 校验数据是否为空 解决处理BeanUtils.copyProperties(obj1,obj2);为空数据的处理
 * @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 {
        //根据传入的属性名称构造属性的set方法名
        String str = methodName.substring(0, 1).toUpperCase()+methodName.substring(1);
        String methodNameNew = "set"+str;
        Method[] methods = entity.getClass().getMethods();
        for(Method method:methods){
            //如果方法同名则执行该方法(不能用于实体中有重载方法的情况)
            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);
        }
    }

相关文章

  • springdataJPA更新操作如何防止丢失数据

    当用springdatajpa自带save()进行更新操作时,会先在底层执行merge()的一个动作,而执行mer...

  • 增强app的健壮性

    1.app中有操作数据库的行为的,需要在appdelegate中进行检测操作,防止用户内部的存储损坏或者数据丢失。

  • 事务隔离级别和各个级别的并发访问问题

    更新丢失(MySQL所有事务隔离级别在数据库层面上均可避免)事务A对数据进行操作时,事务B也在对同一数据更新操作并...

  • redis学习笔记(四) 持久化

    1. 引子 redis所有数据保存在内存中,为防止数据丢失,redis通过对数据的更新异步地保存到磁盘中来实现持久...

  • Ucache 灾备云 数据搬迁服务

    (IDC彭帅) 数据备份是容灾和搬迁的基础,是指为防止系统出现操作失误或系统故障导致数据丢失,而将全部或部分数据集...

  • SpringDataJpa数据库操作

    那么我们传统的JDBC的做法是使用很多的if语句根据传过来的查询条件来拼sql,mybatis的做法也类似,由于m...

  • 这样操作,防止公司数据文件丢失!

    公司数据一旦发生丢失现象,就容易给公司造成损失,情况严重时真的是不可想象的。作为公司的一员,为避免这种情况的发生,...

  • mysql备份

    数据备份和冗余的区别 备份:能够防止机器故障以及人为误操作带来的数据丢失,例如将数据库文件保存在其他地方 冗余:数...

  • Spring和SpringDataJpa整合详解

    Spring和SpringDataJpa整合详解 一、概述 SpringBoot操作数据库有多种方式,如 JDBC...

  • 数据库备份分类

    数据库备份是保证数据安全,防止系统出现操作失误或系统故障导致数据丢失的一项重要举措。数据备份主要有以下三种分类方式...

网友评论

      本文标题:springdataJPA更新操作如何防止丢失数据

      本文链接:https://www.haomeiwen.com/subject/kyoowftx.html