基于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进行自增的策略。


目录
相关文章
|
7月前
|
存储 SQL 算法
搞定了 6 种分布式ID,分库分表哪个适合做主键?
在《ShardingSphere5.x分库分表原理与实战》系列的第七篇文章中,作者探讨了分布式ID在分库分表中的重要性,以及如何利用`ShardingSphere-jdbc`的多种主键生成策略。文章介绍了`UUID`、`NanoID`、自定义雪花算法和`CosId`等策略的优缺点,并警告不要在SQL中手动拼接主键字段。此外,文章还展示了如何配置这些策略,并提醒读者`CosId`在5.2.0版本可能不可用。最后,文章讨论了如何自定义分布式主键生成算法,并强调选择策略时要考虑全局唯一性、性能和易用性。
752 1
|
设计模式 算法 Java
浩鲸科技:为什么要用雪花ID替代数据库自增ID?
浩鲸科技:为什么要用雪花ID替代数据库自增ID?
107 1
|
7月前
|
SQL Oracle 关系型数据库
SQL PRIMARY KEY 约束- 唯一标识表中记录的关键约束
SQL NOT NULL 约束用于强制确保列不接受 NULL 值。这意味着该字段始终包含一个值,而不允许插入新记录或更新记录时不提供此字段的值。
147 0
|
关系型数据库 MySQL
MySQL查询之 如何删除主键和添加主键等修饰词
MySQL查询之 如何删除主键和添加主键等修饰词
141 0
|
关系型数据库 数据库 索引
主键和唯一索引的区别
主键和唯一索引的区别
162 0
|
SQL 关系型数据库 MySQL
mysql ,如何将B表的字段f 作为A表的主键s的外键?
假设您已经有两个表A和B,且它们都已经有字段,其中A表的主键为s,B表中的字段为f。要将B表的字段f作为A表的主键s的外键,可以使用以下的 SQL 语句来实现:
|
算法 Scala 数据库
4. 分库分表之后, id 主键如何处理?
4. 分库分表之后, id 主键如何处理?
121 0
4. 分库分表之后, id 主键如何处理?
|
关系型数据库 Java 数据库
使用jpa在postgresql数据库中创建主键自增表
jpa依赖 org.springframework.boot spring-boot-starter-data-jpa org.
3401 0
|
关系型数据库 MySQL 索引
MySQL约束——添加主键约束(联合主键)、删除主键约束
MySQL约束——添加主键约束(联合主键)、删除主键约束
2524 0
|
SQL Oracle 关系型数据库
oracle中查看一张表是否有主键,主键在哪个字段上
oracle中查看一张表是否有主键,主键在哪个字段上