数据库主键生成策略通常有
其中Table策略通用性好,在任何数据库下都可以通用。在Jspxcms中,这张表的名称:hibernate_sequences
(7.0及之前版本为t_id_table
)。里面分别记录了表名及其相应的ID值。
代码中的domain实体类中有ID生成方式的注解。以com.jspxcms.core.domain.Info
为例:
@Id
@Column(name = "f_info_id", unique = true, nullable = false)
@TableGenerator(name = "tg_cms_info", pkColumnValue = "cms_info", initialValue = 1, allocationSize = 10)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "tg_cms_info")
public Integer getId() {
return this.id;
}
其中initialValue
是主键的起始值,allocationSize
是JPA一次获取ID的数量。由于获取ID需要消耗性能,所以不会插入一条数据就获取一个ID,而是一次性获取10个、50个、100个,甚至更多。这会导致ID不连续,比如一次获取10个ID后,只用了一两个,程序就重启了,那剩下的八九个ID就作废了。
如果第三方程序要插入数据到这些表中,就要非常注意ID的问题。需要自行修改hibernate_sequences
表中的ID值,否则会导致主键冲突的异常。
需要特别注意的是,hibernate_sequences
中的next_val
(ID值)是实际使用ID+2*allocationSize,比如当前使用的ID值是100,allocationSize是10,那么ID表中的next_val
好像应该110,但实际上是120。
自己修改hibernate_sequences
的next_val
时需要特别小心,看到next_val
为100时,可以使用101作为自己的ID,但应该把next_val
改到一个更大值,不是改成102,也不是110,而是要改成120(allocationSize为10的情况下)。而allocationSize
默认的值是50,在需要大量插入数据的情况下,程序还会把这个值设置的更大。所以不要怕浪费ID值,把next_val
改大一点总是安全的。