SpringBoot+SpringDataJpa 通用审核逻辑

SpringBoot + SpringDataJpa 通用审核逻辑

场景

最近再写一个sql 模拟数据的一个小工具,里面涉及到了提交表数据的审核、提交字段数据的审核,以及一些关键字的审核,而这些审核逻辑都是相同的,假设一个一个写的话,那么会基本同样的代码写多次,这样的代码不符合代码重用原则,也就是代码冗余,所以这篇文章主要是基于 SpringBoot+SpringDataJpa实现统一审核逻辑的代码。

代码

统一审核信息

@Data
@MappedSuperclass
public abstract class BaseAuditEntity implements Serializable {
    @Enumerated(EnumType.STRING)
    @ApiModelProperty("审核状态")
    private AuditStateEnums auditState = AuditStateEnums.waiting;
    @ApiModelProperty("审核时间")
    private LocalDateTime auditTime;
    @ApiModelProperty("意见")
    private String verdict;
}

表信息实体类

@Data
@Entity
@ApiModel("表信息")
@Where(clause = "deleted = false")
@EqualsAndHashCode(callSuper = true)
@EntityListeners(AuditingEntityListener.class)
public class TableInfo extends BaseAuditEntity {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long Id;
	@ApiModelProperty("用户Id")
	private String userId;
	@ApiModelProperty("表名")
	private tableName;
	@ApiModelProperty("表注释")
	private tableComment;
	@ApiModelProperty("字段信息")
	private List<Feild> feildInfo;
	@CreatedDate
	@ApiModelProperty("创建时间")
	private LocalDateTime createdAt;
	@ApiModelProperty("是否删除")
	private boolean deleted;
}

字段信息实体类

	@Data
@ApiModel("字段信息")
@Entity(name = "field_info")
@Where(clause = "deleted = false")
@EqualsAndHashCode(callSuper = true)
@EntityListeners(AuditingEntityListener.class)
public class FieldInfo extends BaseAuditEntity {
    private static final long serialVersionUID = 1L;
    @Id
    @ApiModelProperty("主键")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @ApiModelProperty("用户id")
    private String userId;
    @ApiModelProperty("字段名称")
    private String fieldName;
    @ApiModelProperty("内容")
    @Convert(converter = FieldConverter.class)
    private Field fieldContent;
    @ApiModelProperty("是否删除")
    private boolean deleted = false;
    @CreatedDate
    @ApiModelProperty("创建时间")
    private LocalDateTime createdAt;
}

Base Repository 统一审核mapper

@NoRepositoryBean
public interface BaseAuditRepository<T extends BaseAuditEntity, ID extends Serializable> extends JpaRepository<T, ID> {
	/**
     * 审核
     *
     * @param id      id
     * @param s1      审核后状态
     * @param s2      审核前状态
     * @param verdict 审核意见
     * @return int 是否成功
     */
    @Modifying
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    @Query("update #{#entityName} t set t.auditState = :s1, t.verdict = :verdict where t.id = :id and t.auditState = :s2")
    int audit(ID id, AuditStateEnums s1, AuditStateEnums s2, String verdict);
}

TableInfoRepository

public interface TableInfoRepository extends BaseAuditRepository<TableInfo, Long> {
}

FieldInfoRepository

public interface FieldInfoRepository extends BaseAuditRepository<TableInfo, Long> {
}

AuditService 通用审核service

public interface AuditService<T extends BaseAuditEntity, ID extends Serializable> {
    /**
     * 获取审核持久化mapper
     *
     * @return BaseAuditRepository<T, ID>
     */
    BaseAuditRepository<T, ID> getRepository();

    /**
     * 审核
     *
     * @param id         审核id
     * @param event      审核事件
     * @param verdict    意见
     * @return Boolean 是否成功
     */
    default Boolean audit(ID id, AuditEventEnums event, String verdict) {
        BaseAuditRepository<T, ID> repository = this.getRepository();
        if (repository == null) {
            throw new BusinessException("未找到审核持久化mapper");
        }
        switch (event) {
            case accept:
                return this.accept(repository, id);
            case reject:
                return this.reject(repository, id, verdict);
            default:
                throw new BusinessException("未找到审核事件");
        }
    }

    /**
     * 审核通过
     *
     * @param repository mapper
     * @param id         审核id
     * @return Boolean 是否成功
     */
    default Boolean accept(BaseAuditRepository<T, ID> repository, ID id) {
        int row = repository.audit(id, AuditStateEnums.accepted, AuditStateEnums.waiting, null);
        if (1 != row) {
            throw new BusinessException("审核失败");
        }
        return true;
    }

    /**
     * 审核拒绝
     *
     * @param repository mapper
     * @param id         审核id
     * @param verdict    意见
     * @return Boolean 是否成功
     */
    default Boolean reject(BaseAuditRepository<T, ID> repository, ID id, String verdict) {
        int row = repository.audit(id, AuditStateEnums.rejected, AuditStateEnums.waiting, verdict);
        if (1 != row) {
            throw new BusinessException("审核失败");
        }
        return true;
    }
}

TableInfoService

public interface TableInfoService extends AuditService {
}

FieldInfoService

public interface FieldInfoService extends AuditService {
}

TableInfoServiceImpl

public class TableInfoServiceImpl implements TableInfoService {
	@Resource
	private TableInfoRepository tableInfoRepository;
	@Override
    public BaseAuditRepository<FieldInfo, Long> getRepository() {
        return fieldInfoRepository;
    }
}

FieldInfoServiceImpl

public class FieldInfoServiceImpl implements FieldInfoService {
	@Resource
	private FieldInfoRepository fieldInfoRepository;
	@Override
    public BaseAuditRepository<FieldInfo, Long> getRepository() {
        return fieldInfoRepository;
    }
}

main

public class Application {
	@Resource
	private TableInfoService tableInfoService;
	
	public Boolean audit(Long id, AuditEventEnums event){
		return this.tableInfoService.audit(id, event);
	}
}

备注

因为每个实体类都有审核字段 (审核状态、审核时间、审核意见),所以创建了一个BaseAuditEntity 审核抽象类,需要审核的实体类需要继承。
因为每个实体类中审核时都要操作数据库,但是在操作数据库时需要使用实体类对应的mapper,所以创建了BaseAuditRepository用来实现统一管理继承方法的mapper,但是要注意,在接口上需要打上@NoRepositoryBean 注解,假如不打这个注解的话,那么在启动的时候会报错 BaseAuditEntity is not mapped 他会找BaseAuditEntity 中是否有@Entity注解,但是BaseAuditEntity并不是一张表,所以我们不需要创捷这个接口的示例。最后所有的Repository都要继承BaseAuditRepository中的audit审核方法用于后面直接调用。
创建了 AuditSerivce 统一审核服务代码,这个主要就是审核的逻辑代码,但是要注意,这个service中有个getRepository();方法,这个方法是可以指定对应的Repository。
这样就完成了一个基于SpringBoot+SpringDataJpa的统一审核代码!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值