Spring JPA 部分字段更新,灵活控制字段更新、支持(设定:可更新字段、不可更新字段)
程序员文章站
2024-03-01 00:01:58
...
Spring JPA 部分字段更新,灵活控制字段更新、支持(设定:可更新字段、不可更新字段)
目录
三、编写 UserRepository.class 继承 BaseRepository
五、创建 UserService 继承 BaseService
一、创建 实体类 User.java
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;
}
二、编写基础 BaseRepository.class
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 <T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T>, QuerydslPredicateExecutor<T> {
}
三、编写 UserRepository.class 继承 BaseRepository
package com.example.demo.repository;
import com.example.demo.entity.User;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends BaseRepository<User, Integer> {
}
四、创建 BaseService.class
package com.example.demo.service;
import com.example.demo.repository.BaseRepository;
import java.io.Serializable;
public abstract class BaseService<R extends BaseRepository<T, ID>, T, ID extends Serializable> {
}
五、创建 UserService 继承 BaseService
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<UserRepository, User,Integer> {
}
以上五步基本文件关系创建,文件目录关系(见图-1)
编写业务代码:
六、UserService 进行编写业务代码
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<UserRepository, User,Integer> {
@Autowired
UserRepository userRepository;
public User saveUser(User data) {
User save = null;
Optional<User> 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 配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.weijuhe</groupId>
<artifactId>wjh</artifactId>
<version>0.0.1</version>
<packaging>war</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--QueryDSL支持-->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
</dependency>
<!--QueryDSL支持-->
<!-- 单元测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- 单元测试-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--Query DSL-->
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
<!--Query DSL-->
</plugins>
</build>
</project>
工具类文件 JpaUtil
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<String> emptyNames = new HashSet<String>();
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<String> emptyNames = new HashSet<String>();
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);
}
}
上一篇: MySQL中使用FREDATED引擎实现跨数据库服务器、跨实例访问
下一篇: Retrofit的使用