java通过注解实现分表详解
更新时间:2024年11月08日 08:22:20 作者:LeoLi_4
这篇文章主要为大家详细介绍了java如何通过注解实现分表,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下
写在前面
在业务开发中,需要根据不同的渠道存储产品销售信息,由于单个渠道数据量比较大,放在一个表中存储不合适,需要针对每个渠道单独存储。
代码实现
定义注解和切面
定义注解
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface DynamicTable { /** * 需要分割的表名 * @return */ String tableName(); /** * 后缀key * @return */ String separateKey(); }
切面处理逻辑
@Aspect @Component @Slf4j public class DynamicTableAspect { /** * 用于SpEL表达式解析. */ private SpelExpressionParser parser = new SpelExpressionParser(); /** * 用于获取方法参数定义名字. */ private DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer(); private static final String TABLE_NAME = "tableName"; private static final String TABLE_SUFFIX = "tableSuffix"; /** * 以注解为切点 */ @Pointcut("@annotation(com.leoli04.DynamicTable)") public void dynamicTable() { } @Around("dynamicTable()") public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature(); Method method = methodSignature.getMethod(); if(method.isAnnotationPresent(DynamicTable.class)){ DynamicTable dynamicTable = (DynamicTable) method.getAnnotation(DynamicTable.class); String key = dynamicTable.separateKey(); // 获取参数 Object[] args = joinPoint.getArgs(); Expression expression = parser.parseExpression(key); // 使用spring的DefaultParameterNameDiscoverer获取方法形参名数组 String[] paramNames = nameDiscoverer.getParameterNames(method); // spring的表达式上下文对象 EvaluationContext context = new StandardEvaluationContext(); // 给上下文赋值 for (int i = 0; i < args.length; i++) { context.setVariable(paramNames[i], args[i]); } RequestDataHelper.setRequestData(new HashMap<String, Object>() {{ put(TABLE_NAME, dynamicTable.tableName()); put(TABLE_SUFFIX, expression.getValue(context)); }}); Object proceed = joinPoint.proceed(); RequestDataHelper.removeRequestData(); return proceed; }else{ Object proceed = joinPoint.proceed(); return proceed; } } }
mybatis拦截器
上面代码在处理切面逻辑中有如下代码:
RequestDataHelper.setRequestData(new HashMap<String, Object>() {{ put(TABLE_NAME, dynamicTable.tableName()); put(TABLE_SUFFIX, expression.getValue(context)); }}); Object proceed = joinPoint.proceed(); RequestDataHelper.removeRequestData();
这段其实是在代码逻辑中设置了上下面,切面逻辑处理完了之后,再把上下文内容去除。目的是为了给mybatis拦截器使用当前请求的上下文内容。
拦截器内部利用的是是mubatis动态表名,内容如下:
@Configuration @Slf4j public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor(); // 添加分页插件 mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor()); // 动态表名插件 DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor(); dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> { // 获取参数方法 Map<String, Object> paramMap = RequestDataHelper.getRequestData(); if (CollectionUtils.isNotEmpty(paramMap)) { var tableNameParam = (String) paramMap.get("tableName"); paramMap.forEach((k, v) -> log.info(k + "----" + v)); if(tableNameParam.equals(tableName)){ // 获取传递的参数 String tableSuffix = (String) paramMap.get("tableSuffix"); if(StringUtils.isBlank(tableSuffix)){ return tableName; }else{ // 组装动态表名 return tableName + "_" + tableSuffix; } } } return tableName; }); mybatisPlusInterceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor); return mybatisPlusInterceptor; } }
到此这篇关于java通过注解实现分表详解的文章就介绍到这了,更多相关java分表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
一篇超详细的SpringBoot整合MybatisPlus的文章
这篇文章主要介绍了springboot整合Mybatis-plus的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2021-07-07深入浅析ArrayList 和 LinkedList的执行效率比较
这篇文章主要介绍了ArrayList 和 LinkedList的执行效率比较的相关资料,需要的朋友可以参考下2017-08-08Stream distinct根据list某个字段去重的解决方案
这篇文章主要介绍了Stream distinct根据list某个字段去重,stream的distinct去重方法,是根据 Object.equals,和 Object.hashCode这两个方法来判断是否重复的,本文给大家介绍的非常详细,需要的朋友可以参考下2023-05-05
最新评论