跳到主要内容

主键生成

在插入前生成业务 ID,写入后直接从实体读取。下面以 KeyType.UUID32 为例。

说明

通用配置见主键生成与回填

主键策略

策略本数据源的用法
手工赋值可手工赋值,但 MergeTree 不校验唯一性;省略 ID 时使用列默认值。
自增不提供自增生成键。
UUID字符主键使用 UUID32 或 UUID36。
序列不提供序列主键策略。
自定义可在插入前生成 ID;插入后回调不能读取自增生成键。

Mapper 文件的主键策略

INSERT 可直接绑定应用提供的 ID;selectKey 可在插入前或后执行额外查询,把查询值回填到参数属性。ClickHouse 不返回 JDBC 生成键,不能通过 useGeneratedKeys 取得自增 ID。

使用应用侧 ID

CREATE TABLE event_log (id String, event_name String)
ENGINE = MergeTree ORDER BY id;

如果业务需要唯一 ID,建议在 Java 侧生成,例如 UUID、雪花 ID 或业务号。

ClickHouse 应用侧 ID 映射
@Table("event_log")
public class EventLog {
@Column(value = "id", primary = true, keyType = KeyType.UUID32)
private String id;

@Column("event_name")
private String eventName;
}
Lambda 插入
EventLog event = new EventLog();
event.setEventName("login");

LambdaTemplate lambda = ...;
lambda.insert(EventLog.class)
.applyEntity(event)
.executeSumResult();

String id = event.getId();

KeyType.UUID32 / KeyType.UUID36 属于插入前生成,不依赖 ClickHouse 返回 generated keys。

一次写入多条事件见批量插入

手工指定 ID

实体采用 KeyType.None 时,dbVisitor 使用已赋值的 ID。对于 MergeTree 表,排序键不会检查 ID 是否重复;省略 ID 列时使用该列的默认值:

CREATE TABLE manual_keys (id Int32, name String)
ENGINE = MergeTree ORDER BY id;

INSERT INTO manual_keys (id, name) VALUES (1001, 'first'), (1001, 'second');
INSERT INTO manual_keys (name) VALUES ('without ID');

前两条记录的 ID 均为 1001,第三条为 0。如果业务要求 ID 非空且唯一,应在写入前生成并检查,不能依赖主键冲突异常。

自定义主键生成器

例如,订单号由 beforeApply 在插入前生成并赋给实体,再随 INSERT 写入;处理器可以访问当前连接及映射信息。afterApply 可以执行后置逻辑,但 ClickHouse 不返回自增生成键,不能依赖它回读数据库生成的编号。

生成器的配置见主键生成器