如果多个实体类都有 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. Go 互斥锁 Mutex 源码分析 (一)

    0. 前言 锁作为并发编程中的关键一环,是应该要深入掌握的. 1. 锁 1.1 示例 实现锁很简单,示例如下: var global int func main() { var mu sync.Mut ...

  2. 全网最适合入门的面向对象编程教程:37 Python常用复合数据类型-列表和列表推导式

    全网最适合入门的面向对象编程教程:37 Python 常用复合数据类型-列表和列表推导式 摘要: 在 Python 中,列表是一个非常灵活且常用的复合数据类型.它允许存储多个项,这些项可以是任意的数据 ...

  3. 关于phpstudy小坑 经典数据库报错 1044

    经典数据库报错  1044   权限问题 一个很经典的问题 使用的集成环境的phpstudy ,  一直都挺好的  但是每次删除后不能创建同名的数据库   最后发现原来默认的只有一个库  在这个库下面 ...

  4. 使用 Nuxt 的 showError 显示全屏错误页面

    title: 使用 Nuxt 的 showError 显示全屏错误页面 date: 2024/8/26 updated: 2024/8/26 author: cmdragon excerpt: 摘要: ...

  5. USB入门系列(一)认识USB

    认识USB usb的类型 接头外形上 USB类型 描述 USB-A 最广泛的接口标准 USB-B 一般用于打印机.扫描仪.USBHUB等外部USB设备(j-tag就用到了) USB-C USB-C将成 ...

  6. Element-UI 中使用rules验证

    第一种:写在data中进行验证 <el-form>:代表这是一个表单 <el-form> -> ref:表单被引用时的名称,标识 <el-form> -> ...

  7. 登录Harbor仓库报错:Error response from daemon: Get

    登录Harbor仓库报错: docker login -u admin -p Harbor12345 20.20.10.162 WARNING! Using --password via the CL ...

  8. 安全 – CSP (Content Security Policy)

    前言 之前讲过 CSRF.防 Cookie hacking 的. 也介绍过防 XSS 的 HtmlSanitizer. 今天再介绍 CSP. 参考 Content Security Policy 介绍 ...

  9. Go 学习路线图

    基础阶段 学习内容: 掌握 Go 的基本语法,包括变量.常量.数据类型(如整数.浮点数.字符串.布尔值.数组.切片.映射等).运算符等. 理解程序的控制流,如条件语句(if-else.switch-c ...

  10. .NET 开源高性能 MQTT 类库

    前言 随着物联网(IoT)技术的迅猛发展,MQTT(消息队列遥测传输)协议凭借其轻量级和高效性,已成为众多物联网应用的首选通信标准. MQTTnet 作为一个高性能的 .NET 开源库,为 .NET ...