编辑
2025-08-25
JAVA知识
00
请注意,本文编写于 46 天前,最后修改于 24 天前,其中某些信息可能已经过时。

相关信息

使用场景:当实际业务会产生大量数据时使用分表操作,例如考勤信息按年月日分表、报表信息按年月日分表、也可以按实际业务产生的分类标识进行分表操作

配置类:

java
package com.iagz.cloud.framework.mybatis.config; import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.context.annotation.Bean; import javax.sql.DataSource; import java.sql.*; @Slf4j @AutoConfiguration(before = MybatisPlusAutoConfiguration.class) public class MybatisPlusConfig { // 使用ThreadLocal保存动态表名参数 private static final ThreadLocal<String> PARAM = new ThreadLocal<>(); public static void setParam(String param) { PARAM.set(param); } public static void clearParam() { PARAM.remove(); } @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(DataSource dataSource) { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 添加动态表名拦截器 interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor(dataSource)); log.info("MybatisPlusInterceptor 已创建并配置了动态表名拦截器"); // 可以添加其他拦截器 // interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } @Bean public DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor(DataSource dataSource) { DynamicTableNameInnerInterceptor interceptor = new DynamicTableNameInnerInterceptor(); interceptor.setTableNameHandler((sql, tableName) -> { if ("模板表名".equals(tableName)) { String param = PARAM.get(); if (param != null) { String physicalTableName = "模板表名_" + param; ensureTableExists(dataSource, physicalTableName); return physicalTableName; } } return tableName; }); return interceptor; } // 确保表存在的方法 private synchronized void ensureTableExists(DataSource dataSource, String targetTableName) { if (!checkTableExists(dataSource, targetTableName)) { createTableFromTemplate(dataSource, targetTableName); } } // 检查表是否存在 private boolean checkTableExists(DataSource dataSource, String tableName) { try (Connection connection = dataSource.getConnection()) { DatabaseMetaData metaData = connection.getMetaData(); try (ResultSet resultSet = metaData.getTables(null, null, tableName, new String[]{"TABLE"})) { return resultSet.next(); } } catch (SQLException e) { throw new RuntimeException("检查表是否存在失败: " + tableName, e); } } // 使用 CREATE TABLE ... LIKE 语法创建新表 private void createTableFromTemplate(DataSource dataSource, String targetTableName) { String sourceTableName = "模板表名"; // 1. 首先检查源表是否存在 if (!checkTableExists(dataSource, sourceTableName)) { throw new RuntimeException("模板表 " + sourceTableName + " 不存在,无法创建分表"); } String createSql = "CREATE TABLE " + targetTableName + " LIKE " + sourceTableName; try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) { statement.execute(createSql); log.info("分表创建成功: {} (基于模板表: {})", targetTableName, sourceTableName); } catch (SQLException e) { throw new RuntimeException("创建分表失败: " + targetTableName, e); } } }

service层调用方法

java
@Service public class YourService { private final YourMapper yourMapper; private final MybatisPlusConfig.TableManager tableManager; public void yourMethod(String param) { try { // 设置动态表名参数 MybatisPlusConfig.setParam(param); // 执行数据库操作 yourMapper.selectList(null); } finally { MybatisPlusConfig.clearPanelId(); } } }

本文作者:tiger

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!