JPA
JPA 四种主键生成策略
GenerationType.IDENTITY
多数数据库支持 IDENTITY 列,数据库会在新行插入时自动给 ID 赋值,这也叫做 ID 自增长列
GenerationType.Auto
把主键生成策略交给 JPA 厂商(Persistence Provider),由它根据具体的数据库选择合适的策略,可以是 Table/Sequence/Identity 中的一种。假如数据库是 Oracle,则选择 Sequence
GenerationType.TABLE
有时候为了不依赖于数据库的具体实现,在不同数据库之间更好的移植,可以在数据库中新建序列表来生成主键,序列表一般包含两个字段:第一个字段引用不 同的关系表,第二个字段是该关系表的最大序号。这样,只需要一张序列就可以用于多张表的主键生成。
GenerationType.SEQUENCE
Oracle 不支持 ID 子增长列而是使用序列的机制生成主键 ID
JPA 映射 UUID 主键
// Entity
@Id
@Type(type = "org.hibernate.type.PostgresUUIDType")
private UUID id = UUID.randomUUID();
// Dao
public interface DemoDao extends JpaRepository<Demo,UUID> {
public Demo findById(UUID uuid);
}
Demo demo =demoDao.findById(UUID.fromString("127757ac-571c-9052-cdd9-a31f91d15972"));
PostgreSQL
PostgreSQL uuid 主键类型
使用 UUID 作为主键的目的
降低 Serial 类型这种自增 ID 线性特征,UUID 作为随机生成的字符串,让 ID 更离散,增强系统的反爬虫能力(至少避免通过 ID 的线性增加来爬取内容这种最简单的爬取方式)
主键的生成方式
主键的两种生成方式各有优缺点
- 在应用程序中生成 UUID,并插入到数据库
- 通过使用数据库扩展自动生成,具体包括两个实现:
pgcrypto
,uuid-ossp
应用程序生成
// 因为 UUID 不重复,所以避免了同步问题
UUID.randomUUID().toString()
数据库扩展
pgcrypto
-- 安装扩展
CREATE EXTENSION pgcrypto;
-- 查询安装的所有扩展
\dx
-- 生成 UUID
SELECT gen_random_uuid();
-- 作为主键使用
CREATE SCHEMA IF NOT EXISTS developerworks;
CREATE TABLE developerworks.contacts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT,
email TEXT
);
uuid-ossp
create extension "uuid-ossp";
select uuid_generate_v4();
-- 或者
select uuid_generate_v1();
通过 sql 文件安装
psql -d dbname -U dbuser -f /usr/local/Cellar/postgresql/10.5/share/postgresql/uuid-ossp.sql
postgresql 10的扩展,在这个目录/usr/local/Cellar/postgresql/10.5/share/postgresql