其他部分和正常关系数据库的mybatis过程一样,就是在写mapper.xml文件时需要注意一下:
这里我使用DbTable
这个类存储一个表的信息,并作为parameterType
传入mapper.xml
。这里表名以及字段数量名称都是根据DbTable
中内容而定(这里表的字段是一个timestamp
类型加n
个jsonb
类型字段)。
@Data
@Slf4j
@AllArgsConstructor
public class DbTable {
// 表名
private String tableName;
// 表类型,Enum(项目需求,分为STAT和ALM)
private TableType tableType;
// 所有Json字段的名称
private List<String> fieldList;
// tsdb配置,包括chunk_time_interval和add_retention_policy
private Map<String ,String> tsdbConfigMap;
// Json字段里面的key的名称,与题目无关可忽略
private Map<String, List<String>> jsonFieldMap;
public DbTable(String tableName, TableType tableType, List<String> fieldList, String tsdbConfigJson, Map<String, List<String>> jsonFieldMap) throws JsonProcessingException {
this.tableName = tableName;
this.tableType = tableType;
this.fieldList = fieldList;
this.tsdbConfigMap = JacksonUtil.getInstc().json2map(tsdbConfigJson);
this.jsonFieldMap = jsonFieldMap;
}
}
动态表名需要xml文件使用${}
,而不能用#{}
,虽然不能防注入。
<mapper namespace="tsdb.dbcreate.mapper.InitTsdbMapper">
<update id="initTsdb" parameterType="DbTable">
CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE; // 记得加这一句,否则会出现找不到tsdb中函数的错误。
DROP TABLE IF EXISTS ${tableName};
CREATE TABLE ${tableName} (
timestamp timestamp without time zone NOT NULL,
<foreach collection="fieldList" item="fieldName" separator="," close="">
${fieldName} jsonb
</foreach>
);
SELECT * FROM create_hypertable('${tableName}', 'timestamp', chunk_time_interval =>INTERVAL '${tsdbConfigMap.chunkTimeInterval}');
SELECT add_retention_policy('${tableName}', INTERVAL '${tsdbConfigMap.dropTimeInterval}');
</update>
</mapper>
主要就是这句:CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;
不加我这儿老是报错,虽然本地Psql已经CREATE EXTENSION
了。
另外:我在stackoverflow网站里也发现了同样的问题,他们是对tsdb的函数加个schma前缀,如图。这里我没遇到,可以参考一下。