springboot+mybatis-plus多表写入查询,自动建表

文章介绍了如何利用Mybatis-Plus的DynamicTableNameInnerInterceptor插件实现动态表名,以及结合TableNameHandler处理不同活动的分表。同时,展示了如何创建ShardTableHandler类检查并自动创建数据库表,通过执行SQL脚本来完成建表操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有些是按日期自动新建表,有些需要手动生成表

我这是新建活动时手动新建的表,一个活动一个表

一、先说分表写入和分表查询,使用mybatis-plus官方的DynamicTableNameInnerInterceptor插件,用法很简单

1、修改MybatisPlusConfig文件,新增一下代码

DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
dynamicTableNameInnerInterceptor.setTableNameHandler(new MyTableNameHandler());//动态表名插件
mybatisPlusInterceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);

整体代码如下:

@Configuration
public class MybatisPlusConfig {

    /**
     * 配置分页等
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();

        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        dynamicTableNameInnerInterceptor.setTableNameHandler(new MyTableNameHandler());//动态表名插件
        mybatisPlusInterceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);

        // 分页插件
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        // 乐观锁
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        // 防止全表更新与删除
        mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());

        return mybatisPlusInterceptor;
    }



}

2、新增TableNameHandler文件

public class MyTableNameHandler implements TableNameHandler {
    
    private static final ThreadLocal<String> SUFFIX = new ThreadLocal<>();
    public static void setData(String suffix) {
        SUFFIX .set(suffix);
    }

    @Override
    public String dynamicTableName(String sql, String tableName) {
        String suffix = SUFFIX .get();
        if(StringUtils.isNotBlank(suffix)){
            SUFFIX .remove();
            return tableName + suffix;
        }
        return tableName;
    }
}

3、使用方法

查询使用:

        在查询前加入以下代码即可

        MyTableNameHandler.setData("_"+表名称);

        比如:user表,加入以上代码就会变为user_20230101之类的

插入使用:

        用法类似,也在写入以上代码,可以完善一下

 public boolean save(String dynamicTableName, Users users) {
        //将动态表名放到请求参数中(表名)
        if(StringUtils.isNotBlank(dynamicTableName)){
            MyTableNameHandler.setData("_"+dynamicTableName);
        }
        //和以前使用一样
        userMapper.insert(users);
    }

二、搭配代码自动建表     

        1、新建ShardTableHandler数据库操作类


@Component
public class ShardTableHandler {

    /**
     * 引入数据源,也可以是 DruidDataSource,此处根据项目配置来定
     */
    @Resource
    private DruidDataSource dataSource;


    /**
     * 验证表是否存在,按xxx维度进行分表
     */
    public void checkExistTable(String tableName) {
        Connection conn = null;
        try {
            conn = dataSource.getConnection();

            String[] types = new String[]{"TABLE", "VIEW"};
            // 查询当前数据源下的表数据
            ResultSet rs = conn.getMetaData().getTables(conn.getCatalog(), conn.getSchema(), "%", types);

            boolean exist = false;
            // 判断是否存在
            while (rs.next()) {
                String tableStr = rs.getString("TABLE_NAME");
                if (tableStr.equals(tableName)) {
                    exist = true;
                    break;
                }
            }

            // 不存在则创建
            if (!exist) {
                System.out.println("创建表");

                // 获取文件的URL
                File file = ResourceUtils.getFile("classpath:create_user.sql");
                // 转成string输入文本
                String content = FileUtils.readFileToString(file, StandardCharsets.UTF_8);

                // 获取sql
                String sql = String.format(content, tableName);
                PreparedStatement ps = conn.prepareStatement(sql);
                ps.execute();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}

        2、新建create_user.sql数据库建表文件

CREATE TABLE `%s` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `openid` varchar(40) COLLATE utf8mb4_bin NOT NULL,
  `user_name` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '姓名',
  `user_phone` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '手机号',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `headimgurl` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `uni_openid` (`openid`) USING BTREE COMMENT '唯一openid',
  UNIQUE KEY `uni_phone` (`user_phone`) USING BTREE COMMENT '唯一手机号'
) ENGINE=InnoDB AUTO_INCREMENT=185 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC;

        3、引入与使用

//引入
@Resource
private ShardTableHandler shardTableHandler;

随意在需要建表前调用此方法即可新建数据库表

//date是日期区分|使用其他区分也行
shardTableHandler.checkExistTable("user_"+date);

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值