jpa中只有save方法并没有update方法,那他是怎么实现更新的呢,
首先对于save方法,他会先根据id在数据库里查询,如果没查到数据就会insert一条数据;
如果查到数据,就会update一条数据,但是如果要存入的对象有的字段没有赋值(为null),他就会把null也会插入数据库,那原来这条数据有的字段有值也会被覆盖掉,为了避免这种情况发生,就要做出调整。
一.继承SimpleJpaRepository,改写save方法
package cn.qingsec.test.report.repository;
import cn.qingsec.test.report.utils.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import javax.persistence.EntityManager;
import java.util.Optional;
/**
* @Author: Liu
* @Date: 2023/08/30
* @Description:
*/
@Slf4j
public class ZeusJpaRepository<T, ID> extends SimpleJpaRepository<T, ID> {
private JpaEntityInformation<T, ?> jpaEntityInformation;
/**
* Creates a new {@link ZeusJpaRepository} to manage objects of the given {@link JpaEntityInformation}.
*
* @param entityInformation must not be {@literal null}.
* @param entityManager must not be {@literal null}.
*/
@Autowired
public ZeusJpaRepository(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.jpaEntityInformation = entityInformation;
}
/**
* 覆盖原来实现,不更新null字段
* @author 隐
* @date 2020-03-16
* @param entity
* @param <S>
* @return
*/
@Override
public <S extends T> S save(S entity) {
ID id = (ID) jpaEntityInformation.getId(entity);
if (id != null) {
Optional<T> op = findById(id);
if (op.isPresent()) {
T t = op.get();
BeanUtils.copyPropertiesWithoutNull(entity, t);
entity = (S) t;
}
}
return super.save(entity);
}
}
二.重写BeanUtils
package cn.qingsec.test.report.utils;
import org.springframework.beans.FatalBeanException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* @Author: Liu
* @Date: 2023/08/30
* @Description:
*/
public class BeanUtils extends org.springframework.beans.BeanUtils {
/**
* bean copy不复制null值
* @author 隐
* @date 2018-11-10
* @param source
* @param target
*/
public static void copyPropertiesWithoutNull(Object source, Object target) {
if(source == null || target == null){
return;
}
Class<?> actualEditable = target.getClass();
Class<?> sourceClass = source.getClass();
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
for (PropertyDescriptor targetPd : targetPds) {
if(targetPd.getWriteMethod() == null) {
continue;
}
PropertyDescriptor sourcePd = getPropertyDescriptor(sourceClass, targetPd.getName());
if(sourcePd == null || sourcePd.getReadMethod() == null) {
continue;
}
try {
Method readMethod = sourcePd.getReadMethod();
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source);
setValue(target, targetPd, value);
} catch (Exception ex) {
throw new FatalBeanException("Could not copy properties from source to target", ex);
}
}
}
/**
* 设置值到目标bean
* @param target
* @param targetPd
* @param value
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private static void setValue(Object target, PropertyDescriptor targetPd, Object value) throws IllegalAccessException, InvocationTargetException {
// 这里判断以下value是否为空
if (value != null) {
Method writeMethod = targetPd.getWriteMethod();
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(target, value);
}
}
}
三.在启动类上加注解
@EnableJpaRepositories(repositoryBaseClass = ZeusJpaRepository.class)
四.加上注解
在实体类上加上注解
@DynamicUpdate @DynamicInsert
4159

被折叠的 条评论
为什么被折叠?



