springboot~jpa优雅的处理isDelete的默认值
如果多个实体类都有 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实体,不使用默认的CreatedBy和LastModifiedBy
@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的默认值的更多相关文章
- Spring boot Jpa添加对象字段使用数据库默认值
Spring boot Jpa添加对象字段使用数据库默认值 jpa做持久层框架,项目中数据库字段有默认值和非空约束,这样在保存对象是必须保存一个完整的对象,但在开发中我们往往只是先保存部分特殊的字段其 ...
- 补习系列(19)-springboot JPA + PostGreSQL
目录 SpringBoot 整合 PostGreSQL 一.PostGreSQL简介 二.关于 SpringDataJPA 三.整合 PostGreSQL A. 依赖包 B. 配置文件 C. 模型定义 ...
- 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础授权权限
上一篇<[原]无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限>介绍了实现Shiro的基础认证.本篇谈谈实现 ...
- 【原】无脑操作:IDEA + maven + Shiro + SpringBoot + JPA + Thymeleaf实现基础认证权限
开发环境搭建参见<[原]无脑操作:IDEA + maven + SpringBoot + JPA + Thymeleaf实现CRUD及分页> 需求: ① 除了登录页面,在地址栏直接访问其他 ...
- 带着新人学springboot的应用08(springboot+jpa的整合)
这一节的内容比较简单,是springboot和jpa的简单整合,jpa默认使用hibernate,所以本质就是springboot和hibernate的整合. 说实话,听别人都说spring data ...
- springboot+jpa+mysql+redis+swagger整合步骤
springboot+jpa+MySQL+swagger框架搭建好之上再整合redis: 在电脑上先安装redis: 一.在pom.xml中引入redis 二.在application.yml里配置r ...
- SpringBoot JPA + H2增删改查示例
下面的例子是基于SpringBoot JPA以及H2数据库来实现的,下面就开始搭建项目吧. 首先看下项目的整体结构: 具体操作步骤: 打开IDEA,创建一个新的Spring Initializr项目, ...
- SpringBoot JPA懒加载异常 - com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy
问题与分析 某日忽然发现在用postman测试数据时报错如下: com.fasterxml.jackson.databind.JsonMappingException: could not initi ...
- SpringBoot如何优雅的使用RocketMQ
目录 SpringBoot如何优雅的使用RocketMQ SpringBoot如何优雅的使用RocketMQ MQ,是一种跨进程的通信机制,用于上下游传递消息.在传统的互联网架构中通常使用MQ来对上下 ...
- IDEA SpringBoot+JPA+MySql+Redis+RabbitMQ 秒杀系统
先放上github地址:spike-system,可以直接下载完整项目运行测试 SpringBoot+JPA+MySql+Redis+RabbitMQ 秒杀系统 技术栈:SpringBoot, MyS ...
随机推荐
- C 语言多文件编译
C 语言中的多文件编程通常涉及将代码分散在几个不同的源文件(.c 文件)和头文件(.h 文件)中.这么做可以帮助你组织大型项目,提高代码的重用性,便于团队合作,分离接口和实现,以及加快编译时间.下面是 ...
- Charles的https抓包方法及原理/下载ssl/http证书【转】
Charles的https抓包方法及原理/下载ssl/http证书 本文的Charles,适应windows/MAC/IOS/Android,避免抓包HTTPS失败和乱码: charles如果不配 ...
- AI将诗意装进口袋!合合信息扫描全能王“扫描书籍”功能优化上线
人间最美四月天,正是读书好时节.4月20日至23日,正值"世界读书日"之际,合合信息旗下扫描全能王联合上海首家图像小说主题书店--安古莱姆书店,共同发起"春天正是读书天& ...
- Angular 学习笔记 work with zip (压缩文件格式)
最近在做批量创建. 上回说到了 读写 excel, 那么就可以通过 excel 的资料来创建资料了.但是资料经常会有图片,而 excel 里面放图片有点不太好. 于是就想 upload excel 的 ...
- Google Analytics & Ads 学习笔记 2 (GA4 版本)
首先去 control panel admin 升级 GA4 https://support.google.com/analytics/answer/9744165?hl=en 它其实是开多一个 pr ...
- SD卡的基本知识与选购指南
1.SD卡与TF卡 SD 卡:又叫标准 SD 卡,其尺寸大小为 32 x 24 x 2.1 mm ,一般用于数码相机.声卡和采集卡等设备. TF 卡:又叫 micro SD 卡,其尺寸大小为 15 x ...
- 图片 电力电网行业IT运维方案
智能电网背景下,电力.电网企业信息化逐渐渗透到其业务链的各个环节,云计算.物联网.移动互联网等新技术的应用,更驱动信息化与业务创新深度融合.电力.电网企业集团信息系统群逐渐朝着一体化方向发展,信息链越 ...
- C#/.NET/.NET Core技术前沿周刊 | 第 7 期(2024年9.23-9.30)
前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录.追踪C#/.NET/.NET Core领域.生态的每周最新.最实用.最有价值的技术文章.社区动态.优质项目和学习资源等. ...
- electron的两个进程
electron 有两个类别的进程,一个是主进程,另一个是渲染进程 主进程: 启动后一直存在的,相当于一个树的主干并不会展示出来,是看不到的所有跟系统资源交互的操作都在这里进行操控渲染进程,新建或销毁 ...
- .Net 反射的学习
// 反射 // 一切从 type 开始 2 种拿到 type 的方式 // 作用:动态的操作对象 获取属性 方法 特性 // 1. 拿到对象的 type // typeof(类); // 2. 拿到 ...