Spring JPA 部分字段更新,灵活控制字段更新、支持(设定:可更新字段、不可更新字段)
目录
一、创建 实体类 User.java
二、编写基础 BaseRepository.class
三、编写 UserRepository.class 继承 BaseRepository
四、创建 BaseService.class
五、创建 UserService 继承 BaseService
业务代码:
六、UserService 进行编写业务代码
七、创建控制器调用 测试
package com.example.demo.entity;
import lombok.Data;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.*;
@Data
@Entity
@Table(name = "po_system_user")
@DynamicUpdate
public class User {
/** 版本号 */
private static final long serialVersionUID = -4011850649077119561L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String username;
private String password;
private String nick;
private String mobile;
private String email;
private String auth;
private int iframe;
private String theme;
private int status;
@Column(name = "last_login_ip")
private String lastLoginIp;
@Column(name = "last_login_time")
private int lastLoginTime;
private int ctime;
private int mtime;
}
package com.example.demo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.NoRepositoryBean;
import java.io.Serializable;
@NoRepositoryBean
public interface BaseRepository extends JpaRepository, JpaSpecificationExecutor, QuerydslPredicateExecutor {
}
package com.example.demo.repository;
import com.example.demo.entity.User;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends BaseRepository {
}
package com.example.demo.service;
import com.example.demo.repository.BaseRepository;
import java.io.Serializable;
public abstract class BaseService, T, ID extends Serializable> {
}
package com.example.demo.service;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.stereotype.Service;
@Service
public class UserService extends BaseService {
}
以上五步基本文件关系创建,文件目录关系(见图-1)
package com.example.demo.service;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import com.example.demo.util.JpaUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class UserService extends BaseService {
@Autowired
UserRepository userRepository;
public User saveUser(User data) {
User save = null;
Optional selectData = userRepository.findById(data.getId());
if (selectData.isPresent()) {
String[] Field = {"nick", "theme"}; //更新 Field指定允许字段
JpaUtil.copyNotNullPropertiesAllow(data, selectData.get(), Field);
save = userRepository.save(selectData.get());
} else {
userRepository.save(data); //新增
}
return save;
}
}
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Controller
@RequestMapping("/")
public class IndexController {
@Autowired
UserService userService;
@GetMapping("index")
public void index() {
User data = new User();
data.setId(1);
data.setNick("只更新,允许的字段");
userService.saveUser(data);
}
}
访问测试:http://127.0.0.1:9011/index ,控制台输出如下:
pom.xml 配置
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.3.1.RELEASE
com.weijuhe
wjh
0.0.1
war
demo
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
runtime
org.projectlombok
lombok
1.16.20
provided
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
com.querydsl
querydsl-apt
provided
com.querydsl
querydsl-jpa
org.springframework.boot
spring-boot-starter-test
org.springframework.boot
spring-boot-maven-plugin
com.mysema.maven
apt-maven-plugin
1.1.3
process
target/generated-sources/java
com.querydsl.apt.jpa.JPAAnnotationProcessor
package com.example.demo.util;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class JpaUtil {
/**
* @param src
* @param target
* @name 排除指定字段
*/
public static void copyNotNullPropertiesExclude(Object src, Object target, String[] Field) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src, Field, true));
}
/**
* @param src
* @param target
* @name 允许指定字段
*/
public static void copyNotNullPropertiesAllow(Object src, Object target, String[] excludeField) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src, excludeField, false));
}
/**
* @param src
* @param target
* @name 允许指定字段
*/
public static void copyPropertiesAllow(Object src, Object target, String[] excludeField) {
BeanUtils.copyProperties(src, target, getPropertyNames(src, excludeField, false));
}
/**
* @param source
* @return
* @name 筛选忽略字段
*/
public static String[] getNullPropertyNames(Object source, String[] excludeField, boolean tag) {
String[] result = null;
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set emptyNames = new HashSet();
for (java.beans.PropertyDescriptor pd : pds) {
if (pd.getName().equals("baseData")) {
continue;
} else {
Object srcValue = src.getPropertyValue(pd.getName());
//pd.getName() , 存在 Allow ,Exclude
boolean contains = Arrays.asList(excludeField).contains(pd.getName());
if (srcValue == null || contains == tag) {
emptyNames.add(pd.getName());
}
}
}
result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
/**
* @param source
* @return
* @name 筛选忽略字段 , 不去掉null
*/
public static String[] getPropertyNames(Object source, String[] excludeField, boolean tag) {
String[] result = null;
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set emptyNames = new HashSet();
for (java.beans.PropertyDescriptor pd : pds) {
if (pd.getName().equals("baseData")) {
continue;
} else {
Object srcValue = src.getPropertyValue(pd.getName());
//pd.getName() , 存在 Allow ,Exclude
boolean contains = Arrays.asList(excludeField).contains(pd.getName());
if (contains == tag) {
emptyNames.add(pd.getName());
}
}
}
result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
}