hibernate中索引和@NaturalId之间的区别

时间:2017-07-29 23:25:55

标签: java hibernate

有一些关于自然标识符的文章,我在那里读到,自然标识符增强了对hibernate中主要使用字段的查找。 In this post,他们描述了使用特定字段查找任何数据的自然标识符要好得多。他们还描述了自然标识符由hibernate索引,而hibernate通过使用该索引来提高查找性能。

据我所知,还有一些方法可以为特定字段创建索引,并使用这种方式可以获得查找性能。那么使用自然标识符而非一般索引的优势是什么?

举个例子,我可以创建一个具有正确索引的实体类,如

@Entity
@Table(name = "users", indexes = {
    @Index(columnList = "username", name = "users_username")
})
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "username", unique = true)
    private String username;

    @Column(name = "email_id")
    private String email;

    ------------

}

其他方式我可以创建一个没有索引但是自然标识符的实体,如

@Entity
@Table(name = "users")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @NaturalId
    @Column(name = "username", unique = true)
    private String username;

    @Column(name = "email_id")
    private String email;

    ------------

}

根据定义,两者都以相同的方式工作,并且两者都在引擎盖下使用索引方法。从技术上讲,索引和自然标识符之间有什么区别?哪种推荐方法以及它如何优于另一种?

1 个答案:

答案 0 :(得分:1)

当您使用@NaturalId时,Hibernate将维护自然ID到主键的映射。例如,如果您有一个类似以下的用户实体:

//This is pseudo-code

User {
@Id
long id;

@NaturalId
String username;
}

Hibernate将存储哪些用户名映射到哪些ID,这意味着如果一个实体已经与会话对象关联,Hibernate可以通过自然id从会话加载它。 (此功能也可以扩展到二级缓存。)

索引将创建一个附加列,以按排序顺序保留原始索引列的所有行。可以在索引列上进行二进制搜索,以减少为查找而检查的行数。

我相信唯一约束会自动索引Postgres中的相应列。我个人使用唯一约束和自然id注释。