使用MySQL和Oracle进行Hibernate自动密钥生成

使用MySQL和Oracle进行Hibernate自动密钥生成,第1张

使用MySQL和Oracle进行Hibernate自动密钥生成

即使您使用时

GenerationType.AUTO
没有任何SEQUENCE特定参数,也将无法保存分配标识符

如果您愿意做出一些妥协,则有一些解决方法:

  1. 一种方法是切换到分配的标识符。您可以使用适用于MySQL和Oracle的UUID标识符,也可以手动分配值。

  2. 另一种方法是使用自定义表生成器

首先,您定义一个可识别的接口:

    public interface Identifiable<T extends Serializable> {    T getId();}

然后扩展表生成器:

    public class AssignedTableGenerator extends TableGenerator {    @Override    public Serializable generate(SessionImplementor session, Object obj) {        if(obj instanceof Identifiable) { Identifiable identifiable = (Identifiable) obj; Serializable id = identifiable.getId(); if(id != null) {     return id; }        }        return super.generate(session, obj);    }}

此生成器能够将分配的标识符与合成的生成的标识符混合:

    doInTransaction(session -> {    for (int i = 0; i < 5; i++) {        session.persist(new AssignTableSequenceIdentifier());    }    AssignTableSequenceIdentifier tableSequenceIdentifier = new AssignTableSequenceIdentifier();    tableSequenceIdentifier.id = -1L;    session.merge(tableSequenceIdentifier);    session.flush();});

生成以下语句:

    select tbl.next_val from sequence_table tbl where tbl.sequence_name=default for updateinsert into sequence_table (sequence_name, next_val)  values (default,1)update sequence_table set next_val=2  where next_val=1 and sequence_name=defaultselect tbl.next_val from sequence_table tbl where tbl.sequence_name=default for updateupdate sequence_table set next_val=3  where next_val=2 and sequence_name=defaultselect tbl.next_val from sequence_table tbl where tbl.sequence_name=default for updateupdate sequence_table set next_val=4  where next_val=3 and sequence_name=defaultselect tbl.next_val from sequence_table tbl where tbl.sequence_name=default for updateupdate sequence_table set next_val=5  where next_val=4 and sequence_name=defaultselect tbl.next_val from sequence_table tbl where tbl.sequence_name=default for updateupdate sequence_table set next_val=6  where next_val=5 and sequence_name=defaultselect identityvs0_.id as id1_0_0_ from assigneTableIdentifier identityvs0_ where identityvs0_.id=-1insert into assigneTableIdentifier (id) values (1, 2)insert into assigneTableIdentifier (id) values (2, 4)insert into assigneTableIdentifier (id) values (5, -1)

对于Oracle,您可以结合SEQUENCE和分配的生成器,如本文所述。

简而言之,请考虑以下生成器:

public class AssignedSequenceStyleGenerator     extends SequenceStyleGenerator {    @Override    public Serializable generate(SessionImplementor session,         Object obj) {        if(obj instanceof Identifiable) { Identifiable identifiable = (Identifiable) obj; Serializable id = identifiable.getId(); if(id != null) {     return id; }        }        return super.generate(session, obj);    }}

您可以将其映射到您的实体,如下所示:

@Id@GenericGenerator(    name = "assigned-sequence",    strategy = "com.vladmihalcea.book.hpjp.hibernate.identifier.AssignedSequenceStyleGenerator",    parameters = @org.hibernate.annotations.Parameter(        name = "sequence_name",         value = "post_sequence"    ))@GeneratedValue(    generator = "assigned-sequence",     strategy = GenerationType.SEQUENCE)private Long id;

所有代码都可以在GitHub上使用,并且像一个超级按钮一样工作。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5102700.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-17
下一篇 2022-11-16

发表评论

登录后才能评论

评论列表(0条)

保存