illustrate
There are multiple tables in the same database, and the suffixes are separated by dates.
For example, there are three tables:
map_record_202301
map_record_202302
map_record_202303
Since the mapper corresponds to a table, but the table structure is exactly the same now, how to specify and operate a certain table? How to map with entity class in mybatisplus? please look down
Participating dependencies/libraries
MybatisPlus 3.4.3.4
Concrete operation
1. Add dependencies
<!-- 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. Add MybatisPlus interceptor
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. Use
You only need to pass in the correct table name before operating a certain table.
If you need to create a table, such as creating a new map_record_202304 table, the statement to create the table needs to be implemented by yourself. For examples, please refer to the appendix
// 静态的,无论在哪里都可以这样用
// 表示要操作map_record_202301表
MONTH_DATA.set(“map_record_202301”);
// recordMapper是MybatisPlus的mapper
List<MapRecord> recordList1 = recordMapper.selectList(null);
4. Appendix
Mapper
Note: MapRecord is an entity class, corresponding to the map_record_202301 table (it is this type of table, not just corresponding to this table)
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@Mapper
public interface MapRecordMapper extends BaseMapper<MapRecord> {
}
Entity class MapRecord
@NoArgsConstructor
@AllArgsConstructor
@Data
public class MapRecord implements Serializable {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* uuid
*/
private String uuid;
}
Create a new table map_record_202304 example
Note: Use ${tableName} instead of #{tableName}, because when passing in the table name, you need connectors instead of placeholders.
@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
Life is short,
why not forget it,
let go of the burden in your heart, and
move forward calmly.