外键约束的应用层维护

1.前言

一般来说 对于不同表格之间的属性约束 我们通常直接使用数据库已经实现好的外键来完成 但是数据库底层实现的外键他的性能很差 这是因为在执行数据库修改操作时 他需要遍历其他所有的表来找出其中可能相关联的属性 一并进行数据库修改(应用层的维护则只需要遍历所有关联外键所在的表) 当然 性能差还有其他很多的原因 这里就提供一个思路 所以要求我们可以通过应用层(业务层)来自行维护一个外键约束

2.实现思路

aop+注解
我们会通过aop去拦截所有形式的数据库修改业务 因为不同形式的数据库修改操作(比如removeById和removeByIds)都有可能影响到其他的约束属性 所以不能够遗漏任何情况 对于任何形式的数据库修改操作而言 都需要对可能存在的约束属性进行检查
同时 也会根据注解来标识外键/主键 同时储存一些相关信息(约束主键所在的表以及属性等等) 注解内部的属性也会提供一些默认值

3.注解实现

1.级联枚举类

所谓级联 其实就是在对某个表格的某条记录执行数据库修改操作时 他的影响会传递给其他所有相关联的记录
有两种策略 一种就是只提醒用户 让用户去做具体决定 另一种就是绕过用户 直接进行当前记录以及相关联的所有记录的数据库修改操作
我们可以设计一个枚举类型来储存有限个的级联策略

/*** 级联策略 所谓级联 其实就是对某条记录的影响会传递给其他相关联的记录* DEFAULT表示默认策略 即提示用户 让用户做具体决定* DELETE表示激进策略 不问用户 直接删除/更新当前记录以及有关联的所有记录*/
public enum ForeignCascade {DEFAULT, DELETE
}

2.ForeignField注解

利用该可选注解我们可以用于标识外键属性/主键属性
在真正应用该注解时 如果主表属性为id 就可以直接全部采取默认值 则不需要为主表属性作用该注解 这就是可选注解的理解

/*** Documented注解在于会将该注解加入到javadoc文档中* Target注解在于设置该注解的作用类型 比如类、方法、属性等等* Retention注解在于设置该注解的作用周期 取值为RUNTIME表示可以作用于编译运行完整的阶段* Repeatable注解作用是该注解可以在同一个地方同时设置多次 并且需要依赖于一个容器储存 本质上 多次使用就相当于在外部封装一层容器*/
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(ForeignField.ForeignFields.class)
public @interface ForeignField {// 主表类Class<?> value() default Object.class;// 主表类Class<?> mainTable() default Object.class;// 主表属性名String mainField() default "id";// 对应字段String column() default "";// 级联策略ForeignCascade cascade() default ForeignCascade.DEFAULT;// 容器@Documented@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@interface ForeignFields {ForeignField[] value() default {};}
}

3.ForeignTable注解

利用该可选注解我们可以用于标识外键/主键所在表格

/*** Documented注解的作用在于会将该注解加入到javadoc文档中* Target注解的作用在于该注解只能作用于类上*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ForeignTable {// 表名String value() default "";// 表名String name() default "";
}

3.属性信息类/表格信息类实现

1.属性信息类

/*** 该类是属性信息类*/
@Getter
@Setter
public class ForeignFieldInfo {// 当前属性private Field field;// 当前属性对应字段private String column;// 当前属性所在的表格信息类private ForeignTableInfo table;// 引用的属性集合private List<ForeignFieldInfo> mainFields;// 被引用的属性集合private List<ForeignFieldInfo> subFields;// 级联策略private ForeignCascade cascade;// 设置属性 如果属性是私有属性的话 那么就不可以直接由外界访问 这时候 我们应该开放权限public void setField(Field field) {// 表明任意权限的变量都可以访问 即使是private也行field.setAccessible(true);this.field = field;}// 追加引用属性public void addMainField(ForeignFieldInfo mainField) {// 如果集合不存在的话 那么就先创建集合 如果参数已经存在的话 那么就不追加 否则的话 就直接追加if (mainFields == null) {mainFields = new ArrayList<>();} else if (mainFields.contains(mainField)) {return;}mainFields.add(mainField);}// 追加被引用属性public void addSubField(ForeignFieldInfo subField) {// 如果集合不存在的话 先创建集合 如果已经存在 考虑参数是否存在于集合 如果存在 那就不添加 反之则需要添加if (subFields == null) {subFields = new ArrayList<>();} else if (subFields.contains(subField)) {return;}subFields.add(subField);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/65287.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】斐波那契数列

已知Fibonacci数列为1,1,2,3,5,8,13,…&#xff0c;用递归法编写求Fibonacci数的函数&#xff0c;在主函数中输入一个自然数&#xff0c;输出不小于该自然数的最小的一个Fibonacci数。 #include <stdio.h> int Fib(int f) {if (f < 2) return 1;else return Fib(f - …

前端知识补充—CSS

CSS介绍 什么是CSS CSS(Cascading Style Sheet)&#xff0c;层叠样式表, ⽤于控制⻚⾯的样式 CSS 能够对⽹⻚中元素位置的排版进⾏像素级精确控制, 实现美化⻚⾯的效果. 能够做到⻚⾯的样式和结构分离 基本语法规范 选择器 {⼀条/N条声明} 1&#xff09;选择器决定针对谁修改…

elasticsearch 杂记

8.17快速安装与使用 系统&#xff1a;ubuntu 24 下载地址&#xff1a; https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.17.0-linux-x86_64.tar.gz 解压后进入目录&#xff1a;cd ./elasticsearch-8.17.0 运行&#xff1a;./bin/elasticsearch 创…

在git commit之前让其自动执行一次git pull命令

文章目录 背景原因编写脚本测试效果 背景原因 有时候可以看到项目的git 提交日志里好多 Merge branch ‘master’ of …记录。这些记录是怎么产生的呢&#xff1f; 是因为在本地操作 git add . 、 git commit -m "xxxxx"时&#xff0c;没有提前进行git pull操作&…

c# RSA加解密工具,.netRSA加解密工具

软件介绍 名称: c# RSA加解密工具,.netRSA加解密工具依赖.net版本: .net 8.0工具类型: WinForm源码下载 c# RSA加解密工具,.netRSA加解密工具 依赖项 WinFormsRSA.csproj <Project

地理数据库Telepg面试内容整理-如何在数据库中优化大规模空间数据的查询性能

优化大规模空间数据查询的性能是一个复杂但关键的任务,特别是在需要处理海量的地理信息时。空间数据通常涉及复杂的几何对象、空间关系和大范围的查询操作,因此,优化空间数据的查询性能通常需要综合考虑存储、索引、查询方法等多个方面。以下是一些优化大规模空间数据查询性…

GitCode 光引计划投稿|智能制造一体化低代码平台 Skyeye云

随着智能制造行业的快速发展&#xff0c;企业对全面、高效的管理解决方案的需求日益迫切。然而&#xff0c;传统的开发模式往往依赖于特定的硬件平台&#xff0c;且开发过程繁琐、成本高。为了打破这一瓶颈&#xff0c;Skyeye云应运而生&#xff0c;它采用先进的低代码开发模式…

FFmpeg推拉流命令

命令简介 它可以将本地的视频/音频流推送到服务器&#xff0c;也可以将服务器上的音视频流拉到本地。 推流命令的命令格式 ffmpeg -re -i [输入文件] -c:v [视频编码器] -c:a [音频编码器] -f [输出格式] [推流地址] 参数解析 -re 表示采用实时模式&#xff0c;以原始速度…

使用git管理项目版本

Pycharm git-创建本地仓库\创建分支\合并分支\回溯版本\加入git后文件颜色代表的含义_python中git显示不同颜色-CSDN博客 主要几个命令&#xff1a; git status 查看已提交文件 git checkout -b dev 创建并切换到新分支&#xff0c;是各分支的头指针 git symbolic-ref HEAD re…

iOS从Matter的设备认证证书中获取VID和PID

设备认证证书也叫 DAC, 相当于每个已经认证的设备的标识。包含了 VID 和 PID. VID: Vendor ID &#xff0c;标识厂商 PID: Product ID&#xff0c; 标识设备的 根据 Matter 对于设备证书的规定&#xff0c;DAC证书subject应该包含VID 和 PID. 可通过解析 X509 证书读取subject…

关于分布式数据库需要了解的相关知识!!!

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于关于分布式数据库方面的相关内容&a…

【前沿 热点 顶会】AAAI 2025中与目标检测有关的论文

CP-DETR: Concept Prompt Guide DETR Toward Stronger Universal Object Detection&#xff08;AAAI 2025&#xff09; 最近关于通用物体检测的研究旨在将语言引入最先进的闭集检测器&#xff0c;然后通过构建大规模&#xff08;文本区域&#xff09;数据集进行训练&#xff0…

EdgeX Core Service 核心服务之 Core Command 命令

EdgeX Core Service 核心服务之 Core Command 命令 一、概述 Core-command(通常称为命令和控制微服务)可以代表以下角色向设备和传感器发出命令或动作: EdgeX Foundry中的其他微服务(例如,本地边缘分析或规则引擎微服务)EdgeX Foundry与同一系统上可能存在的其他应用程序…

计算机网络安全

网络安全主要用于保证网络的可用性&#xff0c;以及网络中所传输信息的完整性和机密性。 网络安全设计 网络安全防范体系在整体设计过程中应遵循以下9 项原则。 (1)木桶原则。对信息进行均衡、全面的保护。木桶的最大容积取决于最短的一块木板。网络信息系统是一个复杂的计算机…

《计算机组成及汇编语言原理》阅读笔记:p86-p115

《计算机组成及汇编语言原理》学习第 6 天&#xff0c;p86-p115 总结&#xff0c;总计 20 页。 一、技术总结 1.if statement 2.loop 在许多编程语言中&#xff0c;有类种循环&#xff1a;一种是在程序开头检测条件(test the condition),另一种是在程序末尾检测条件。 3.C…

如何给负载均衡平台做好安全防御

在现代网络架构中&#xff0c;负载均衡&#xff08;Load Balancing&#xff09;扮演着至关重要的角色。它不仅负责将流量分配到多个服务器以确保高效的服务交付&#xff0c;还作为第一道防线来抵御外部攻击。为了保护您的应用程序和服务免受潜在威胁&#xff0c;必须对负载均衡…

【ES6复习笔记】生成器(11)

什么是生成器函数 生成器函数是一种特殊的函数&#xff0c;它可以在执行过程中暂停并保存当前状态&#xff0c;然后在需要时恢复执行。生成器函数通过 yield 关键字来实现暂停和恢复执行的功能。 生成器函数的基本用法 定义生成器函数&#xff1a;使用 function* 关键字来定…

nodejs开发命令行工具

一个简单的 Node.js CLI 工具的开发流程 开发一个命令行工具&#xff08;CLI&#xff09;是一个非常有用的技能&#xff0c;Node.js 提供了强大的库和模块来帮助你快速构建 CLI 应用。下面是一个简单的指南&#xff0c;教你如何使用 Node.js 开发一个命令行工具。 第一步&…

WebRTC服务质量(09)- Pacer机制(01) 流程概述

WebRTC服务质量&#xff08;01&#xff09;- Qos概述 WebRTC服务质量&#xff08;02&#xff09;- RTP协议 WebRTC服务质量&#xff08;03&#xff09;- RTCP协议 WebRTC服务质量&#xff08;04&#xff09;- 重传机制&#xff08;01) RTX NACK概述 WebRTC服务质量&#xff08;…

Linux高级--2.4.5 靠协议头保证传输的 MAC/IP/TCP/UDP---协议帧格式

任何网络协议&#xff0c;都必须要用包头里面设置写特殊字段来标识自己&#xff0c;传输越复杂&#xff0c;越稳定&#xff0c;越高性能的协议&#xff0c;包头越复杂。我们理解这些包头中每个字段的作用要站在它们解决什么问题的角度来理解。因为没人愿意让包头那么复杂。 本…