说明
在同一个数据库里边有多张表,后缀以日期分隔开。
例如有三张表:
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数据,避免多线程数据冲突。所以使用ThreadLocalpublic 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();}@Overridepublic String dynamicTableName(String sql, String tableName) {if (this.tableNames.contains(tableName)){if (MONTH_DATA.get()==null){// 绝对不会走这里,因为在操作表的时候都会提前设置好表名,MONTH_DATA.get()一定不为nullLocalDate 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
人生苦短,
何必念念不忘,
放下心中包袱,
从容向前走。