Jspxcms主键生成机制

2017-07-13 17:09 阅读

数据库主键生成策略通常有

  • 自增主键。依赖数据库的功能,mysql、sqlserver有主键自增功能,oracle、db2则没有。
  • 数据库序列。依赖数据库的功能,mysql没有序列。
  • UUID。不依赖数据库。通过程序产生一个32位的不重复的字符串。由于字符串过于长,作为主键容易影响数据库性能。
  • Table策略。使用一个单独的数据库表来记录其他其他表的主键值,模仿数据库序列的功能。

其中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_sequencesnext_val时需要特别小心,看到next_val为100时,可以使用101作为自己的ID,但应该把next_val改到一个更大值,不是改成102,也不是110,而是要改成120(allocationSize为10的情况下)。而allocationSize默认的值是50,在需要大量插入数据的情况下,程序还会把这个值设置的更大。所以不要怕浪费ID值,把next_val改大一点总是安全的。

QQ咨询
电话
微信
微信扫码咨询