適合場(chǎng)景
在使用Spring Data JPA的時(shí)候,在使用UUID作為主鍵的時(shí)候,通常都會(huì)使用system-uuid作為主鍵生成策略,類似配置如下:
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
private String id;
我們都知道,使用save方法保存實(shí)體的時(shí)候JAP會(huì)根據(jù)主鍵判斷是新增(主鍵為空或者數(shù)據(jù)庫表中無該主鍵)還是更新(數(shù)據(jù)庫表中有該主鍵)。
而且,在使用這種如上配置的時(shí)候無論實(shí)體的主鍵是否為空,只要在表中不存在,都會(huì)再次生成主鍵,也就是沒辦法通過給id屬性賦值的形式來自定義實(shí)體的id。
而在一些場(chǎng)景下,會(huì)有自定義主鍵的需求,比如主鍵來源于其他第三方系統(tǒng),這時(shí)候我們期望的還是使用第三方系統(tǒng)的主鍵作為主鍵以表示同一條數(shù)據(jù),這就需要我們能夠?qū)崿F(xiàn)自定義主鍵生成策略,并且JPA也提供了這樣的通道。
自定義主鍵生成策略
Spring Data JPA可以通過實(shí)現(xiàn)org.hibernate.id.IdentifierGenerator接口來自定義主鍵生成器,而同時(shí)也提供了許多的內(nèi)置生成器,就如上文中的system-uuid生成器,使用uuid2生成策略實(shí)現(xiàn)主鍵生成,也有實(shí)現(xiàn)自增的主鍵生成器:IncrementGenerator。
根據(jù)需求,可以通過繼承org.hibernate.id.UUIDGenerator生成器來實(shí)現(xiàn)自定義ID:
/**
* 自定義UUID生成器
* @author sevenlin
*/
public class CustomUUIDGenerator extends UUIDGenerator {
@Override
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
Object id = FieldUtil.readField(object, "id");
if (id != null) {
return (Serializable) id;
}
return super.generate(session, object);
}
}
有了自定義主鍵生成器之后就可以通過如下配置指定該生成器:
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "custom-uuid")
@GenericGenerator(name = "custom-uuid", strategy = "com.sevenlin.dal.CustomUUIDGenerator")
private String id;
這樣,就可以實(shí)現(xiàn)自定義ID,同時(shí)保留原來的主鍵生成策略不變。