如果多个实体类都有 isDelete 字段,并且你希望在插入时为它们统一设置默认值,可以采取以下几种方法来减少代码重复:

1. 使用基类(抽象类)

创建一个基类,其中包含 isDelete 字段和 @PrePersist 方法。然后让所有需要这个字段的实体类继承这个基类。

示例代码:

import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist; @MappedSuperclass
public abstract class BaseEntity { protected Integer isDelete; @PrePersist
public void prePersist() {
if (isDelete == null) {
isDelete = 0; // 设置默认值为0
}
} // Getter 和 Setter
public Integer getIsDelete() {
return isDelete;
} public void setIsDelete(Integer isDelete) {
this.isDelete = isDelete;
}
}

然后在其他实体类中继承 BaseEntity

import javax.persistence.Entity;
import javax.persistence.Id; @Entity
public class MyEntity extends BaseEntity { @Id
private Long id; // 其他字段、getter 和 setter
}

2. 使用 AOP(面向切面编程)

通过 Spring AOP 创建一个切面,在插入操作时检查并设置 isDelete 的默认值。这种方式不需要修改每个实体类,适合大规模应用。

示例代码:

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component; import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.lang.reflect.Field; @Aspect
@Component
public class DefaultValueAspect { @PersistenceContext
private EntityManager entityManager; @Before("execution(* com.example.repository.*.save(..))") // 根据你的仓库路径调整
public void setDefaultValues(Object entity) throws IllegalAccessException {
Field[] fields = entity.getClass().getDeclaredFields();
for (Field field : fields) {
if ("isDelete".equals(field.getName())) { // 检查字段名
field.setAccessible(true);
if (field.get(entity) == null) {
field.set(entity, 0); // 设置默认值为0
}
}
}
}
}

3. 使用 JPA 审计功能

使用 Spring Data JPA 的审计功能,通过实现 AuditorAware 接口来统一处理审计字段,包括 isDelete。这种方法适合需要更多审计信息的情况,但实现起来相对复杂。

总结

  • 基类:通过创建一个基类,所有需要 isDelete 字段的实体类都可以继承这个基类,避免重复代码。
  • AOP:使用 AOP 可以在插入时动态处理 isDelete 字段,适合大型项目。
  • JPA 审计功能:适合更复杂的审计需求,但实现较复杂。

选择合适的方法取决于你的项目需求和架构。

使用事件监听@EntityListeners

JPA 提供了事件监听器的功能,你可以定义一个事件监听器来处理所有需要设置默认值的实体类。

示例代码:

import javax.persistence.PostLoad;
import javax.persistence.PrePersist;
import javax.persistence.EntityListeners; public interface DeletedField { Integer getDeletedFlag(); void setDeletedFlag(Integer deletedFlag);
} public class DeleteDefaultValueListener { @PrePersist
public void setDefaultValues(DeletedFlagField deletedFlagField) {
if (deletedFlagField.getDeletedFlag() == null) {
deletedFlagField.setDeletedFlag(0); // 设置默认值为0
}
} } @EntityListeners(DefaultValueListener.class)
@Entity
public class TableUserAccount extends EntityBase implements DeletedFlagField { /**
* 删除标识(逻辑删除),1删除 0未删除
*/
@Column(name = "deleted_flag")
private Integer deletedFlag;
}

4. 扩展JPA,对建立者和更新者的扩展

  • CreatedByField
  • UpdatedByField
  • CreatedByDefaultValueListener
  • UpdatedByDefaultValueListener

CreatedByField

public interface CreatedByField {

	String getCreatedBy();

	void setCreatedBy(String createdBy);

}

扩展EntityBase实体,不使用默认的CreatedByLastModifiedBy

@Getter
@Setter
@MappedSuperclass
@EntityListeners({ AuditingEntityListener.class, UpdatedByDefaultValueListener.class,
CreatedByDefaultValueListener.class })
public abstract class EntityBase implements Serializable, CreatedByField, UpdatedByField { /**
* 创建人
*/
@Column(name = "created_by")
private String createdBy; /**
* 修改人
*/
@Column(name = "updated_by")
private String updatedBy;
}

CreatedByDefaultValueListener

public class CreatedByDefaultValueListener implements ApplicationContextAware {

	private ApplicationContext applicationContext;

	@PrePersist
public void setDefaultValues(CreatedByField createdByField) {
if (createdByField.getCreatedBy() == null) {
if (this.applicationContext.getBean(AuditorAwareImpl.class) != null) {
createdByField.setCreatedBy(
this.applicationContext.getBean(AuditorAwareImpl.class).getCurrentAuditor().orElse("")); }
}
} /**
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
} }

springboot~jpa优雅的处理isDelete的默认值的更多相关文章

  1. Spring boot Jpa添加对象字段使用数据库默认值

    Spring boot Jpa添加对象字段使用数据库默认值 jpa做持久层框架,项目中数据库字段有默认值和非空约束,这样在保存对象是必须保存一个完整的对象,但在开发中我们往往只是先保存部分特殊的字段其 ...

  2. 补习系列(19)-springboot JPA + PostGreSQL

    目录 SpringBoot 整合 PostGreSQL 一.PostGreSQL简介 二.关于 SpringDataJPA 三.整合 PostGreSQL A. 依赖包 B. 配置文件 C. 模型定义 ...

  3. 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础授权权限

    上一篇<[原]无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限>介绍了实现Shiro的基础认证.本篇谈谈实现 ...

  4. 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限

    开发环境搭建参见<[原]无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页> 需求: ① 除了登录页面,在地址栏直接访问其他 ...

  5. 带着新人学springboot的应用08(springboot+jpa的整合)

    这一节的内容比较简单,是springboot和jpa的简单整合,jpa默认使用hibernate,所以本质就是springboot和hibernate的整合. 说实话,听别人都说spring data ...

  6. springboot+jpa+mysql+redis+swagger整合步骤

    springboot+jpa+MySQL+swagger框架搭建好之上再整合redis: 在电脑上先安装redis: 一.在pom.xml中引入redis 二.在application.yml里配置r ...

  7. SpringBoot JPA + H2增删改查示例

    下面的例子是基于SpringBoot JPA以及H2数据库来实现的,下面就开始搭建项目吧. 首先看下项目的整体结构: 具体操作步骤: 打开IDEA,创建一个新的Spring Initializr项目, ...

  8. SpringBoot JPA懒加载异常 - com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy

    问题与分析 某日忽然发现在用postman测试数据时报错如下: com.fasterxml.jackson.databind.JsonMappingException: could not initi ...

  9. SpringBoot如何优雅的使用RocketMQ

    目录 SpringBoot如何优雅的使用RocketMQ SpringBoot如何优雅的使用RocketMQ MQ,是一种跨进程的通信机制,用于上下游传递消息.在传统的互联网架构中通常使用MQ来对上下 ...

  10. IDEA SpringBoot+JPA+MySql+Redis+RabbitMQ 秒杀系统

    先放上github地址:spike-system,可以直接下载完整项目运行测试 SpringBoot+JPA+MySql+Redis+RabbitMQ 秒杀系统 技术栈:SpringBoot, MyS ...

随机推荐

  1. 英文短句“xxx for the rest of us”的意思

    "xxx for the rest of us" 这个短语通常被理解为"为我们所有人"或"为我们剩下的人".为了更好地理解这个短语的意义,我 ...

  2. 常用 DNS 查询速度测试

    测试工具 DNS-Benchmark | GitHub 总结 进过多轮测试,我认为: 223.5.5.5 和 223.6.6.6 平均响应时间最短(223.5.5.5 在教育网内疑似无法连通) 114 ...

  3. SimpleTranslationAIAgent:基于C#与LLM的翻译AI Agent

    基于C#与LLM通过简单对话即可实现文件到文件的翻译任务 该软件是MIT协议完全开源免费的,但是调用LLM的API可能需要费用,但是没关系,赛博菩萨硅基流动与智谱AI等都有免费的模型可调了. 这个Tr ...

  4. Seata 四大模式详解

    分布式事务 参考文章: 分布式事务实战方案汇总 https://www.cnblogs.com/yizhiamumu/p/16625677.html 分布式事务原理及解决方案案例https://www ...

  5. Round #2022/11/26

    问题 B:染色 题目描述 有长度为 \(n\) 的一个序列,编号为 \(1\) 到 \(n\) ,现要对这些元素进行染色标记,若编号 \(i-j\) 为素数,且 \(1\le i < j \le ...

  6. ASP.NET Core – Filter

    介绍 Filter 类似 Middleware,只是它集中在处理 request 的前后, 站 MVC 角度看就是 before 和 after action, 站 Razor Pages 角度就是 ...

  7. 【QT性能优化】QT性能优化之QT6框架高性能网络编程框架实现百万TCP长连接网络服务器:QT是否适合做高性能网络应用?补天云这个视频告诉你在大厂Linux云服务器上的实测结果

    QT性能优化之QT6框架高性能网络编程框架实现百万TCP长连接网络服务器 Ø 简介 本文作者编写了一套基于QT的TCP网络服务器程序和基于QT的TCP客户端程序,在某大厂的云服务器上进行了C1000K ...

  8. keycloak~关于授权码认证中的scope的实践

    前言 在 Keycloak 14.0.0 中,使用 protocol/openid-connect/auth 接口获取授权码时,scope 参数是可选的,但它确实有作用.下面是关于 scope 参数的 ...

  9. SuperMap iServer8C证书过期如何解决

    说明:该问题是SuperMap iServer8.0.2和8.1.0版本云许可模块问题,需要手动更新云许可HTTPS证书,可以升级到官网8.1.1/9D/10i等方式进行解决 针对无法升级或者老项目维 ...

  10. LeetCode 1316. Distinct Echo Substrings (RK哈希)

    题意: 给一个字符串 寻找字符串为(a+a)格式的子串有多少.a+a 格式字符串比如 abcabc, ee 等. 首先O(N^2)枚举子串,然后通过哈希在O(1)复杂度判断子串是否符合要求. RK哈希 ...