@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 注解支持如下属性:
指定生成器唯一名称,在 @GeneratedValue 注解中可以通过该名称引用该主键生成器。例如:
@Entity public class Employee { @Id @TableGenerator(name="empGen") @GeneratedValue(strategy=TABLE, generator="empGen") int id; }
指定每次从生成器分配 ID 号时要增加的数量。假如我们指定 allocationSize=50,那么 OpenJPA 将每次从主键生成表获取ID时增加 50(如果主键生成表当前值为100,获取ID后将变成 150)。OpenJPA 在拿到 100 后,将临时保存到变量中,然后每次分配直接对缓存的变量值主键进行加一操作。当缓存的ID值用完了(即大于 150 时),才去数据库中获取。
可选属性,用于指定数据库实例名。
用于初始化生成指定表主键值时主键生成表 valueColumnName 列的初始化值。例如:
@Entity public class Employee { @Id // 主键生成表的 valueColumnName 列的初始值为 100,生成一次主键后变为 150 @TableGenerator(name="empGen", initialValue=100) @GeneratedValue(strategy=TABLE, generator="empGen") int id; }
指定主键生成表的主键列的名称。例如:
@Entity public class Employee { @Id // 指定主键生成表的主键列名为 GEN_KEY @TableGenerator(name="empGen", pkColumnName="GEN_KEY") @GeneratedValue(strategy=TABLE, generator="empGen") int id; }
为当前主键生成器指定在生成器表中的主键值,用于将这组生成的值与可能存储在表中的其他值区分开来。例如:
@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。
作用与 catalog 属性作用一致,可自行测试;
用来自定义主键生成表的表名称,如果不指定,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; }
定义主键生成表的唯一约束。例如:
@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语句
用来自定义在主键生成表中存储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; }