1. Business background
业务上要求存储数据的时候根据某个字段动态的选择数据要存储的表.
如根据code字段: code->[1001,1002]来进行选择存储的表:
经过下面的配置实现动态表名如 --> table1_1001,table_1002的效果.以此动态生成表名的效果.
Second, the solution
Use the dynamic table name plugin in mybatis-plus, and the version must be 3.1.2 or later .
Requirements, put the data in different tables according to the month. The data in January 2022 is placed in the monitor_accelerometer_rapid202201 table, and the data in February 2022 is placed in the monitor_accelerometer_rapid202202 table. Usually, this requirement is accompanied by the need to create tables for scheduled tasks.
1. Preparation
Explanation: The table really exists, and the new table to be dynamically replaced must have the same structure as the entity class table .
@Data
@TableName("monitor_accelerometer_rapid202201")
public class SensorValue implements Serializable {
private static final long serialVersionUID = 5892027263270309341L;
@TableId(value = "id",type = IdType.AUTO)
private Integer id;
private Integer pointId;
private Integer equipmentId;
private String sensorNo;
@TableField(value = "create_time",fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date sensorTime;
private String sensorValueJson;
}
2. Add the following code to the pagination plug-in configured by mybatis-plus
After the plug-in is configured, it will not affect the use of other paging functions
@Configuration
public class MybatisPlusConfig {
//分页插件总添加动态表名插件
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// DynamicTableNameParser 表名解析器,动态解析表名,ITableNameHandler 表名处理。
DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, ITableNameHandler>(2) {
{
//metaObject 元对象 ;sql 执行的SQL ;tableName 表名
//这里put的key就是需要替换的原始表名,也就是实体类的表名
//这里的tableName就是我们定义的动态表名变量,
put("monitor_accelerometer_rapid202201", (metaObject, sql, tableName) -> {
// 获取传入参数 tableName,tableName的值就是替换后的表名
Object param = getParamValue("tableName", metaObject);
if(param == null){
return tableName;//不带tableName参数就返回原表名
}else {
return param.toString();//带tableName参数就返回新表名
}
});
}});
paginationInterceptor.setSqlParserList(Collections.singletonList(dynamicTableNameParser));
return paginationInterceptor;
}
/**
* 获取动态表tableName参数的值
*/
private Object getParamValue(String title, MetaObject metaObject){
//获取参数
Object originalObject = metaObject.getOriginalObject();
JSONObject originalObjectJSON = JSON.parseObject(JSON.toJSONString(originalObject));
JSONObject boundSql = originalObjectJSON.getJSONObject("boundSql");
try {
JSONObject parameterObject = boundSql.getJSONObject("parameterObject");
return parameterObject.get(title);
}catch (Exception e) {
return null;
}
}
//拆分之后的代码,和上面的方法一样
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 动态表名SQL解析器 DynamicTableNameParser 动态解析表名,ITableNameHandler 表名处理。
DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
Map<String,ITableNameHandler> tableNameHandlerMap = new HashMap<>();
// Map的key就是需要替换的原始表名
tableNameHandlerMap.put("monitor_accelerometer_rapid202201",new ITableNameHandler(){
//metaObject 元对象 ;sql 执行的SQL ;tableName 表名
@Override
public String dynamicTableName(MetaObject metaObject, String sql, String tableName) {
// 获取传入参数 tableName,tableName的值就是替换后的表名
Object param = getParamValue("tableName", metaObject);
if(param == null){
return tableName;//不带tableName参数就返回原表名
}else {
return param.toString();//带tableName参数就返回新表名
}
}
});
dynamicTableNameParser.setTableNameHandlerMap(tableNameHandlerMap);
// 创建SQL解析器集合
List<ISqlParser> sqlParserList = new ArrayList<>();
sqlParserList.add(dynamicTableNameParser);
paginationInterceptor.setSqlParserList(sqlParserList);
return paginationInterceptor;
}
3. Realize the code
control layer
@RequestMapping("/sensorValue")
@RestController
public class SensorValueController {
@Autowired
private SensorValueService sensorValueService;
@RequestMapping("/save")
public String save(SensorValue sensorValue){
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
String time = sdf.format(new Date());
//动态设置表名
String tableName = "monitor_accelerometer_rapid"+time;;
sensorValueService.saveSensorValue(sensorValue,tableName)
}
}
The business layer is slightly
persistent
public interface SensorValueMapper extends BaseMapper<SensorValue> {
@Insert("INSERT INTO monitor_accelerometer_rapid202201 (point_id,equipment_id,sensor_no,create_time,sensor_time,sensor_value_json) " +
"VALUES (#{sensorValue.pointId},#{sensorValue.equipmentId},#{sensorValue.sensorNo},#{sensorValue.createTime},#{sensorValue.sensorTime},#{sensorValue.sensorValueJson})")
boolean saveSensorValue(SensorValue sensorValue, String tableName);
}
Result
Here is the newly added data. If you query the data, pass an additional parameter tableName on the basis of the normal query.
INSERT INTO monitor_accelerometer_rapid202202 (point_id, equipment_id, sensor_no, create_time, sensor_time, sensor_value_json) VALUES (?, ?, ?, ?, ?, ?) ::: [702, 479, L1_JS_1, null, 2022-02-17 18:30:09.823, {
"gX":"0.0","gY":"0.0","gZ":"0.0"}