在postgresql使用mybatis动态创建数据库分区表
1. 整体描述
在java下实现:创建分区表,每个月一个分区表,需要定时任务动态创建数据库表。首先创建主表,然后使用定时任务创建分区表,定时任务使用xxl-job实现,当然也可以使用单体定时任务实现。
2. 前期准备
前期需要先创建出分区表,并验证下创建分区表的语句。
2.1 创建主表语句
我使用的是postgresql,和mysql有些区别,但是大同小异。分区表有三种分区规则,这里使用List,不再赘述,本文主要说下动态见表的功能。这里简单用个test表示范一下。
CREATE TABLE test (
log_id int not null,
ym VARCHAR(20) NOT NULL,
logdate date not null,
log_content VARCHAR(500),
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) PARTITION BY LIST (ym);
2.2 创建分表语句
主表创建之后,我们就可以创建分表了,建表语句如下:
CREATE TABLE test_202506 PARTITION OF test
FOR VALUES IN ('202506');
CREATE TABLE test_202507 PARTITION OF test
FOR VALUES IN ('202507');
这里创建两个分区表,分别是6月和7月的,注意创建的时候,有两个参数,一个是分表名:test_202506,一个是分表规则的值:202506,等我们自动创建表的时候,也需要传入这两个参数。
创建好分表之后,我们执行insert语句,会根据ym字段的值,自动放到对应的分区表里。
2.3 xxl-job
xxl-job实现定时任务,本文不具体描述。可以自己搜下,很多介绍,内容也比较多。
3. 代码实现
3.1 mapper.xml层
在mapper.xml层,新建方法:
<select id="isTableExist" resultType="boolean">
SELECT EXISTS (SELECT 1
FROM information_schema.tables
WHERE table_schema = 'public' AND LOWER(table_name) = LOWER(#{tableName}))
</select>
<update id="createNewTable" parameterType="string">
CREATE TABLE PUBLIC.${tableName} PARTITION OF PUBLIC.TEST FOR VALUES IN
(
${yyyyMM}
);
</update>
两个方法,一个是判断表是否存在,一个是创建表。如果不判断直接创建已经存在的表,会报错。其中,PUBLIC是模式名,可以替换为实际模式名称,我就直接在PUBLIC里测试下。 t a b l e N a m e 和 {tableName}和 tableName和{yyyyMM}是参数,需要传入。
3.2 mapper.java层
/**
* 判断表是否存在
*
* @param tableName 表名
* @return 创建结果
*/
boolean isTableExist(@Param("tableName") String tableName);
/**
* 创建表
*
* @param tableName 表名
* @return 创建结果
*/
public void createNewTable(@Param("tableName") String tableName, @Param("yyyyMM") String yyyyMM);
3.3 service接口层
/**
* 判断表是否存在
*
* @param tableName 表名
* @return 创建结果
*/
boolean isTableExist(String tableName);
/**
* 创建表
*
* @param tableName 表名
* @param yyyyMM 年月
* @return 创建结果
*/
public void createNewTable(String tableName, String yyyyMM);
3.4 service实现层
/**
* 判断表是否存在
*
* @param tableName 表名
* @return 创建结果
*/
@Override
public boolean isTableExist(String tableName) {
return service.isTableExist(tableName);
}
/**
* 创建表
*
* @param tableName 表名
* @param yyyyMM 年月
* @return 创建结果
*/
@Override
public void createNewTable(String tableName, String yyyyMM) {
service.createNewTable(tableName, yyyyMM);
}
3.5 controller层
这里我就不在controller层添加接口了,因为这个是通过定时任务实现的,所以直接添加定时任务就好了。具体代码也在这里贴出了,比较简单,依次调用上面的两个方法就行,如果表不存在就创建。
4. 总结
以上就完成自动建表的功能,结合定时任务组件,即可实现定时创建分区表的功能。