@TableGenerator 注解

@TableGenerator 注解用来定义一个主键生成器(必须为主键生成器指定名称),可以在 @GeneratedValue 注解中使用 generator 属性通过主键生成器名称引用该生成器。可以在实体类或主键字段或属性上指定表生成器。

实例1:自定义主键生成表的主键、ID列以及主键值和每次获取主键后增加大小。

@Entity
public class Employee {
    // ...
    @TableGenerator(
        name="empGen", // 指定主键生成器名称
        table="ID_GEN", // 指定主键生成表名称
        pkColumnName="GEN_KEY", // 指定主键生成表的主键列
        valueColumnName="GEN_VALUE", // 指定主键生成表存储ID的列
        pkColumnValue="EMP_ID", // 指定主键生成表的主键列的值
        allocationSize=1 // 指定每次获取主键ID后自增长大小
    )
    @Id
    @GeneratedValue(strategy=TABLE, generator="empGen")
    int id;
    // ...
}

实例2:自定义主键生成表的主键、ID列以及主键值。每次获取主键后增加大小默认50。

@Entity
public class Address {
    // ...
    @TableGenerator(
        name="addressGen", 
        table="ID_GEN", 
        pkColumnName="GEN_KEY", 
        valueColumnName="GEN_VALUE", 
        pkColumnValue="ADDR_ID")
    @Id
    @GeneratedValue(strategy=TABLE, generator="addressGen")
    int id;
    // ...
}

@TableGenerator 注解支持如下属性:

name(必须的)生成器名称

指定生成器唯一名称,在 @GeneratedValue 注解中可以通过该名称引用该主键生成器。例如:

@Entity
public class Employee {
    @Id
    @TableGenerator(name="empGen")
    @GeneratedValue(strategy=TABLE, generator="empGen")
    int id;
}

allocationSize 每次获取主键增量值

指定每次从生成器分配 ID 号时要增加的数量。假如我们指定 allocationSize=50,那么 OpenJPA 将每次从主键生成表获取ID时增加 50(如果主键生成表当前值为100,获取ID后将变成 150)。OpenJPA 在拿到 100 后,将临时保存到变量中,然后每次分配直接对缓存的变量值主键进行加一操作。当缓存的ID值用完了(即大于 150 时),才去数据库中获取。

catalog 数据库实例名

可选属性,用于指定数据库实例名。

initialValue 初始化值 

用于初始化生成指定表主键值时主键生成表 valueColumnName 列的初始化值。例如:

@Entity
public class Employee {
    @Id
    // 主键生成表的 valueColumnName 列的初始值为 100,生成一次主键后变为 150
    @TableGenerator(name="empGen", initialValue=100)
    @GeneratedValue(strategy=TABLE, generator="empGen")
    int id;
}

pkColumnName 主键列名称

指定主键生成表的主键列的名称。例如:

@Entity
public class Employee {
    @Id
    // 指定主键生成表的主键列名为 GEN_KEY
    @TableGenerator(name="empGen", pkColumnName="GEN_KEY")
    @GeneratedValue(strategy=TABLE, generator="empGen")
    int id;
}

pkColumnValue 生成器在主键生成表中的KEY

为当前主键生成器指定在生成器表中的主键值,用于将这组生成的值与可能存储在表中的其他值区分开来。例如:

@Entity
public class Employee {
    @Id
    // 指定当前表在主键生成表的主键值为 key_employee
    @TableGenerator(name="empGen", pkColumnName="GEN_KEY" pkColumnValue="key_employee")
    @GeneratedValue(strategy=TABLE, generator="empGen")
    int id;
}

注意:如果我们不指定 pkColumnValue 属性值,JPA 提供商将使用默认值。在 OpenJPA 中,使用默认值 DEFAULT。

schema 指定数据表的模式

作用与 catalog 属性作用一致,可自行测试;

table 自定义主键生成表名称

用来自定义主键生成表的表名称,如果不指定,JPA 提供商提供默认值。在 OpenJPA 中,默认值为 openjpa_sequences_table。例如:

@Entity
public class Employee {
    // 使用 ID_GEN 表来存放主键值
    @TableGenerator(name="empGen", table="ID_GEN")
    @Id
    @GeneratedValue(strategy=TABLE, generator="empGen")
    int id;
}

uniqueConstraints 表上的唯一约束

定义主键生成表的唯一约束。例如:

@TableGenerator(name = "my_table", table = "my_generator_table",
        uniqueConstraints = {
            @UniqueConstraint(name = "unique_key", columnNames = {"gen_key"})
        },
        pkColumnName = "gen_key", pkColumnValue = "student")

@GeneratedValue(generator = "my_table", strategy = GenerationType.TABLE)
@Id
private Integer id;

运行上面实例代码,OpenJPA 将输出如下SQL语句:

-- 创建主键生成表
CREATE TABLE my_generator_table (GEN_KEY VARCHAR(255) NOT NULL, SEQUENCE_VALUE BIGINT, PRIMARY KEY (GEN_KEY), UNIQUE unique_key (GEN_KEY)) ENGINE = innodb
-- 创建业务表
-- 获取主键值
SELECT SEQUENCE_VALUE FROM my_generator_table WHERE GEN_KEY = ? FOR UPDATE [params=?]
INSERT INTO my_generator_table (GEN_KEY, SEQUENCE_VALUE) VALUES (?, ?) [params=?, ?]
-- 其他业务SQL语句

valueColumnName 指定存储ID的列名

用来自定义在主键生成表中存储ID的列名称。如果不指定,JPA 厂商将采用默认值。在 OpenJPA 中,默认值为 SEQUENCE_VALUE。例如:

@Entity
public class Employee {
    // 使用 ID_GEN 表中的 EMP_ID 列来存放主键ID
    @TableGenerator(name="empGen", table="ID_GEN", pkColumnValue="EMP_ID")
    @Id
    @GeneratedValue(strategy=TABLE, generator="empGen")
    int id;
}
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号