spring data jpa DynamicUpdate 不起作用的问题解决

参考:https://blog.csdn.net/xiao_xuwen/article/details/53579353

及参考了很多。貌似目前大部分都是先去数据库查一下,然后把不为null的值对应的覆盖下,然后保存。

没找到其他更好的办法,但是为了稍微写的优雅点,调用的方便点,修改如下:

自己定义了repository类,覆盖重写了默认的save方法。另外判断加了是否有dynamicupdate注解,根据是否有注解,来对应的处理 属性null值更新情况。实际就是dynamicupdate的效果

/**
 * @author zhengk
 * @description
 * @since 2018-8-19 0:00
 */
public   class BaseRepositoryImpl<T, ID extends Serializable> extends QuerydslJpaRepository<T,ID>
        implements BaseRepository<T,ID> {

    private final JpaEntityInformation entityInformation;

    private final EntityManager em;

    @Autowired
    public BaseRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) {
        super(entityInformation, entityManager);
        this.entityInformation = entityInformation;
        this.em = entityManager;
    }


    /**
     * save方法,保存或新增
     */
    @Override
    @Transactional
    public <S extends T> S save(S entity) {
        if (entityInformation.isNew(entity)) {
            em.persist(entity);
            return entity;
        } else {
            DynamicUpdate dynamicUpdateValue= entity.getClass().getAnnotation(org.hibernate.annotations.DynamicUpdate.class);

            //如果有动态更新的注解,并且值是true,那么动态更新
            if(dynamicUpdateValue!=null&&dynamicUpdateValue.value()){
                //获取ID
                ID entityId = (ID) entityInformation.getId(entity);
                //查询数据库数据
                T dataFromDb = findById(entityId).get();
                //获取为空的属性-覆盖的时候忽略
                String[] ignoreProperties = getNotNullProperties(entity);
                //用数据库对象对应的信息覆盖实体中属性为null的信息
                BeanUtils.copyProperties(dataFromDb, entity, ignoreProperties);
            }
            //更新
            return em.merge(entity);
        }
    }

    /**
     * 获取对象的不为null的属性
     */
    private static String[] getNotNullProperties(Object src) {
        //1.获取Bean
        BeanWrapper srcBean = new BeanWrapperImpl(src);
        //2.获取Bean的属性描述
        PropertyDescriptor[] pds = srcBean.getPropertyDescriptors();
        //3.获取Bean的空属性
        Set<String> properties = new HashSet<>();
        for (PropertyDescriptor propertyDescriptor : pds) {
            String propertyName = propertyDescriptor.getName();
            Object propertyValue = srcBean.getPropertyValue(propertyName);
            if (propertyValue!=null) {
                properties.add(propertyName);
            }
        }
        return properties.toArray(new String[0]);
    }

}

 

/**
 * @author zhengk
 * @description
 * @since 2018-8-19 8:17
 */
public class BaseRepositoryFactoryBean<R extends JpaRepository<T, ID >, T,
        ID extends Serializable > extends JpaRepositoryFactoryBean<R, T, ID> {
    /**
     * Creates a new {@link JpaRepositoryFactoryBean} for the given repository interface.
     *

     * @param repositoryInterface must not be {@literal null}
    .
     */
    public BaseRepositoryFactoryBean(Class < ? extends R >
                                             repositoryInterface) {
        super(repositoryInterface);
    }

    @Override
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) {
        return new BaseRepositoryFactory(em);
    }

    //创建一个内部类,该类不用在外部访问
    private static class BaseRepositoryFactory<T, ID extends Serializable>
            extends JpaRepositoryFactory {

        private final EntityManager em;

        public BaseRepositoryFactory(EntityManager em) {
            super(em);
            this.em = em;
        }

        //设置具体的实现类是BaseRepositoryImpl
        @Override
        protected BaseRepositoryImpl<T, ID> getTargetRepository(RepositoryInformation information) {
            JpaEntityInformation<?, ?> entityInformation = getEntityInformation(information.getDomainType());

            return getTargetRepositoryViaReflection(information, entityInformation, em);
        }

        //设置具体的实现类的class
        @Override
        protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
            return BaseRepositoryImpl.class;
        }
    }
}

 

@EnableJpaRepositories (repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class)//指定自己的工厂类
@SpringBootApplication
public class NbzlcyApplication {

   public static void main(String[] args) {
      SpringApplication.run(NbzlcyApplication.class, args);
   }
}
/**
 * 自定义基础的仓库类,通过改变集成的仓库不一样,来控制提供的接口
 * zhengk
 * @param <T>
 * @param <ID>
 */
@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T,ID>,QuerydslPredicateExecutor<T> {

}

初步代码是这样的,看后面找到合适的再修改吧

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值