基于Saas主键表生成主键id

简介: 首先需要对当前的id进行拦截操作,也即使用aop的切面Aspect对切点进行拦截,在进行新增的时候进行拦截:也就是说在进行主键的生成时,我们拦截好需要生成的主键,此时就可以对其进行新增操作了,而首要的就是拿到它的primaryKey。由于进行新增操作,通常分为两种情况:通过字节码拿到声明的方法getId,如果此时存在id,则说明此时的操作是更新操作,因此直接返回。如果当前通过字节码拿到的声明方法getTenant,通过租户方法拿到租户id。拿到租户id后,就可以进行主键id获取了。

1.主键生成策略方式

微信图片_20221214032645.png

主键生成策略

2.基于Saas主键表生成主键id流程

由于我们的系统时基于Saas的,因此生成主键时,需要以租户id(TenantId)为基础进行生成。为了生成的id符合我们的租户的要求,通常都会现将租户表建好,然后基于租户表中的租户id进行主键id的生成。此时便产生基于租户id生成主键,那么怎样生成主键id呢?可以查看下图:

微信图片_20221214032648.jpg

                     基于多租户生成方式

3.主键id生成实现的具体方式

首先需要对当前的id进行拦截操作,也即使用aop的切面Aspect对切点进行拦截,在进行新增的时候进行拦截:

@Pointcut("execution(* com.xtt..*.dao.mapper..*.insert*(..))")
public void primaryKeyRule() {}

也就是说在进行主键的生成时,我们拦截好需要生成的主键,此时就可以对其进行新增操作了,而首要的就是拿到它的primaryKey。由于进行新增操作,通常分为两种情况:

批量插入单条插入

因此在通过切点JoinPoint拿到参数,通过实例化来判断当前的实体是列表还是单个操作,如果是单个走单个操作,如果是批量走批量操作:

publicvoiddoBefore(JoinPointjp) {
Objectentity=jp.getArgs()[0];
if (entityinstanceofList) {
setPrimaryKeyBatch((List<Object>)entity);
        } else {
setPrimaryKey(entity, entity.getClass());
        }
    }

此时通过反射拿到声明方法中的字段,下面针对单个新增进行说明:

通过字节码拿到声明的方法getId,如果此时存在id,则说明此时的操作是更新操作,因此直接返回。如果当前通过字节码拿到的声明方法getTenant,通过租户方法拿到租户id。拿到租户id后,就可以进行主键id获取了。

privatevoidsetPrimaryKey(Objectentity, Class<?extendsObject>clazz) {
Longid= (Long)clazz.getDeclaredMethod("getId").invoke(entity);
IntegertenantId;
MethodtenantGet=clazz.getDeclaredMethod("getTenant");
tenantId= (Integer)tenantGet.invoke(entity);
//省略异常处理...// 获取类名称、租户id、需要新增的个数1id=PrimaryKeyUtils.getPrimaryKey(clazz.getSimpleName(), tenantId, 1);
// 然后通过setId 计数进行invokeclazz.getDeclaredMethod(METHOD_SET_ID, Long.class).invoke(entity, id);
// 省略异常处理...}

获取主键id:

publicstaticsynchronizedLonggetPrimaryKey(StringmodelName, IntegertenantId, intcount) {
Stringid= (tenantId==null?SystemConstant.DEFAULT_SYS_TENANT_ID : tenantId) +modelName;
Longcurrent= (Long)DBUtils.getSingle("select getPrimaryKeyWithCount('"+id+"',"+count+") from dual;");
current=current-count+1;
// 省略异常处理...returncurrent;
}

从而实现主键自增的目的,从而实现基于租户id进行自增的策略。


目录
相关文章
|
11月前
|
关系型数据库 索引
DB2查询主键、索引、表约束
DB2查询主键、索引、表约束
795 0
|
安全 数据库
通过E-R理解 主键和外键的关系
实例 现有课程和教师两个实体,课程实体的属性有课程名称、课程编号、课程属性、考试类型;教师实体的属性包括姓名、工号、职称;一门课程可以有多个教师,且每一位教师可以教授多门课程。教师每教授一门课有课序号。
4742 1
通过E-R理解 主键和外键的关系
|
5月前
|
存储 关系型数据库 MySQL
MySQL删除外键、增加外键及删除主键、增加主键
MySQL删除外键、增加外键及删除主键、增加主键
61 0
|
5月前
|
SQL Oracle 关系型数据库
SQL PRIMARY KEY 约束- 唯一标识表中记录的关键约束
SQL NOT NULL 约束用于强制确保列不接受 NULL 值。这意味着该字段始终包含一个值,而不允许插入新记录或更新记录时不提供此字段的值。
129 0
|
5月前
|
存储 数据库
elasticsearch 主键生成策略以及如何指定特定字段为id主键列
elasticsearch 主键生成策略以及如何指定特定字段为id主键列
564 0
|
关系型数据库 MySQL
MySQL查询之 如何删除主键和添加主键等修饰词
MySQL查询之 如何删除主键和添加主键等修饰词
131 0
|
关系型数据库 数据库 索引
主键和唯一索引的区别
主键和唯一索引的区别
153 0
|
SQL 关系型数据库 MySQL
mysql ,如何将B表的字段f 作为A表的主键s的外键?
假设您已经有两个表A和B,且它们都已经有字段,其中A表的主键为s,B表中的字段为f。要将B表的字段f作为A表的主键s的外键,可以使用以下的 SQL 语句来实现:
|
算法 Scala 数据库
4. 分库分表之后, id 主键如何处理?
4. 分库分表之后, id 主键如何处理?
113 0
4. 分库分表之后, id 主键如何处理?
|
关系型数据库 Java 数据库
使用jpa在postgresql数据库中创建主键自增表
jpa依赖 org.springframework.boot spring-boot-starter-data-jpa org.
3387 0