当前位置: 首页> 财经> 创投人物 > 长春建站宣传_咨询公司资质_世界足球排名_百度关键词搜索

长春建站宣传_咨询公司资质_世界足球排名_百度关键词搜索

时间:2025/7/11 14:23:34来源:https://blog.csdn.net/m0_71299382/article/details/144755824 浏览次数:0次
长春建站宣传_咨询公司资质_世界足球排名_百度关键词搜索

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);}
}
关键字:长春建站宣传_咨询公司资质_世界足球排名_百度关键词搜索

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: