【常规】Spring Boot多表查询/修改的配置和快速使用

说明

在同一个数据库里边有多张表,后缀以日期分隔开。
例如有三张表:
map_record_202301
map_record_202302
map_record_202303
由于mapper对应的是一张表,但是现在表结构是完全相同的,如何指定操作某一张表呢?在mybatisplus如何与实体类映射呢?请往下看

参与使用的依赖/库

MybatisPlus 3.4.3.4

具体操作

1、添加依赖

        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3.4</version>
        </dependency>

2、添加MybatisPlus拦截器

import com.baomidou.mybatisplus.extension.plugins.handler.TableNameHandler;
import lombok.extern.log4j.Log4j;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
 * 在mybatisPlus执行SQL语句之前修改表的名字
 */
@Log4j
public class MonthTableNameHandler implements TableNameHandler {

    //用于记录哪些表可以使用该月份动态表名处理器(即哪些表按月分表)
    private List<String> tableNames;
    //构造函数,构造动态表名处理器的时候,传递tableNames参数
    public MonthTableNameHandler(String ...tableNames) {
        this.tableNames = Arrays.asList(tableNames);
    }

    //每个请求线程维护一个month数据,避免多线程数据冲突。所以使用ThreadLocal
    public static final ThreadLocal<String> MONTH_DATA = new ThreadLocal<>();
    //设置请求线程的month数据
    public static void setData(String month) {
        MONTH_DATA.set(month);
    }
    //删除当前请求线程的month数据
    public static void removeData() {
        MONTH_DATA.remove();
    }

    @Override
    public String dynamicTableName(String sql, String tableName) {
        if (this.tableNames.contains(tableName)){
            if (MONTH_DATA.get()==null)
            {
                // 绝对不会走这里,因为在操作表的时候都会提前设置好表名,MONTH_DATA.get()一定不为null
                LocalDate date = LocalDate.now();
                return tableName + "_" + date.format(DateTimeFormatter.ofPattern("yyyyMM"));  //表名增加月份后缀
            }
            return MONTH_DATA.get(); // 返回自定义的表名
        }else{
            return tableName;   //表名原样返回
        }
    }
}

3、使用

只需要在操作某张表的时候,之前传入正确的表名即可。

如果需要创建表,例如新建一张map_record_202304表,创建表的语句需要自己实现,例子请看 附录

// 静态的,无论在哪里都可以这样用 
// 表示要操作map_record_202301表
MONTH_DATA.set(“map_record_202301”);
// recordMapper是MybatisPlus的mapper
List<MapRecord> recordList1 = recordMapper.selectList(null);


4、附录

Mapper

注意:MapRecord是实体类,对应的是map_record_202301 表(是这一类表,并不只是对应这一张表)

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@Mapper
public interface MapRecordMapper extends BaseMapper<MapRecord> {
}

实体类MapRecord

@NoArgsConstructor
@AllArgsConstructor
@Data
public class MapRecord implements Serializable {

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * uuid
     */
    private String uuid;
}

创建新表 map_record_202304 例子

注意:要用 ${tableName} 而不是 #{tableName},因为传入表名的时候要连接符而不能用占位符。

@Mapper
public interface MapRecordMapper extends BaseMapper<MapRecord> {

    @Select("SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'chikycloud'")
    List<String> listTables();

    /**
     * 根据参数tableName建 map_record 表语句
     * 例如 传入的参数为 map_record202303,那么表名就是 map_record202303
     *
     * @param tableName 表名
     */
    @Update("CREATE TABLE `${tableName}`  (\n" +
            "  `id` int(50) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键索引',\n" +
            "  `uuid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '唯一标识 也是唯一索引',\n" +
            "  PRIMARY KEY (`id`, `uuid`) USING BTREE,\n" +
            "  UNIQUE INDEX `uuid_index`(`uuid`) USING BTREE\n" +
            ");")
    void createTable(@Param("tableName") String tableName);

END

人生苦短,
何必念念不忘,
放下心中包袱,
从容向前走。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值