107

您如何定义一个字段,例如email使用 JPA 注释具有索引。我们需要一个非唯一的键,email因为每天有数百万次对该字段的查询,而且没有键它有点慢。

@Entity
@Table(name="person", 
       uniqueConstraints=@UniqueConstraint(columnNames={"code", "uid"}))
public class Person {
    // Unique on code and uid
    public String code;
    public String uid;

    public String username;
    public String name;
    public String email;
}

我已经看到了特定于休眠的注释,但我试图避免特定于供应商的解决方案,因为我们仍在休眠和数据核之间做出决定。

更新:

从 JPA 2.1 开始,您可以这样做。请参阅:此位置不允许使用注释 @Index

4

11 回答 11

226

使用 JPA 2.1,您应该能够做到。

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;

@Entity
@Table(name = "region",
       indexes = {@Index(name = "my_index_name",  columnList="iso_code", unique = true),
                  @Index(name = "my_index_name2", columnList="name",     unique = false)})
public class Region{

    @Column(name = "iso_code", nullable = false)
    private String isoCode;

    @Column(name = "name", nullable = false)
    private String name;

} 

更新:如果您需要使用两列或更多列创建和索引,您可以使用逗号。例如:

@Entity
@Table(name    = "company__activity", 
       indexes = {@Index(name = "i_company_activity", columnList = "activity_id,company_id")})
public class CompanyActivity{
于 2014-03-26T11:02:23.020 回答
38

一个独特的精选索引注释集合

= 规格 =

= ORM框架 =

= Android的 ORM =

= 其他(难以分类) =

  • Realm - iOS / Android 的替代数据库:注释io.realm.annotations.Index
  • Empire-db - 基于 JDBC 的轻量级但功能强大的关系数据库抽象层。它没有通过注解定义模式;
  • Kotlin NoSQL (GitHub) - 一种用于处理 NoSQL 数据库 (PoC) 的反应式和类型安全的 DSL:???
  • Slick - Scala 的反应式功能关系映射。它没有通过注释定义模式。

就去其中之一吧。

于 2015-04-15T12:51:29.310 回答
32

JPA 2.1(最终)增加了对索引和外键的支持!有关详细信息,请参阅此博客。JPA 2.1 是 Java EE 7 的一部分,现已推出 .

如果您喜欢生活在边缘,您可以从他们的maven 存储库(groupId:org.eclipse.persistence, artifactId:eclipselink, version:2.5.0-SNAPSHOT)获取 eclipselink 的最新快照。对于 JPA 注释(一旦它们支持 2.1,它应该与任何提供者一起使用)使用 artifactID:javax.persistence, version:2.1.0-SNAPSHOT。

我将它用于一个直到发布后才会完成的项目,并且我没有注意到任何可怕的问题(尽管我没有对它做任何太复杂的事情)。

更新(2013 年 9 月 26 日):现在 eclipselink 的发布和发布候选版本在中央(主)存储库中可用,因此您不再需要在 Maven 项目中添加 eclipselink 存储库。最新的发布版本是 2.5.0,但也存在 2.5.1-RC3。由于 2.5.0 版本的问题(modelgen 的东西不起作用),我会尽快切换到 2.5.1。

于 2013-04-05T18:48:05.467 回答
10

在 JPA 2.1 中,您需要执行以下操作

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Index;
import javax.persistence.Table;

@Entity(name="TEST_PERSON")
@Table(
    name="TEST_PERSON", 
    indexes = {
       @Index(name = "PERSON_INDX_0", columnList = "age"),
       @Index(name = "PERSON_INDX_1", columnList = "fName"),
       @Index(name = "PERSON_INDX_1", columnList = "sName")  })
public class TestPerson {

    @Column(name = "age", nullable = false)
    private int age;

    @Column(name = "fName", nullable = false)
    private String firstName;

    @Column(name = "sName", nullable = false)
    private String secondName;

    @Id
    private long id;

    public TestPerson() {
    }
}

在上面的示例中,表 TEST_PERSON 将有 3 个索引:

  • 主键 ID 上的唯一索引

  • AGE指数

  • FNAME、SNAME 上的复合索引

注意 1:您可以通过两个具有相同名称的 @Index 注释来获得复合索引

注意 2:您在 columnList 中指定列名而不是 fieldName

于 2014-10-16T15:53:58.847 回答
5

我真的很希望能够以标准化的方式指定数据库索引,但遗憾的是,这不是 JPA 规范的一部分(可能是因为 JPA 规范不需要 DDL 生成支持,这是一种障碍这样的功能)。

因此,您必须为此依赖提供者特定的扩展。Hibernate、OpenJPA 和 EclipseLink 显然确实提供了这样的扩展。我无法确认 DataNucleus,但由于索引定义是 JDO 的一部分,我猜它确实如此。

我真的希望索引支持将在规范的下一个版本中标准化,因此在某种程度上不同意其他答案,我看不出有什么好的理由不在 JPA 中包含这样的东西(特别是因为数据库并不总是在你的控制之下)以获得最佳的 DDL 生成支持。

顺便说一句,我建议下载 JPA 2.0 规范。

于 2010-08-04T15:46:53.330 回答
4

据我所知,没有跨 JPA-Provider 的方式来指定索引。但是,您始终可以直接在数据库中手动创建它们,大多数数据库会在查询计划期间自动获取它们。

于 2010-08-04T12:05:46.070 回答
2

EclipseLink 提供了一个注释(例如@Index)来定义列的索引。有一个使用它的例子。部分示例包括...

firstName 和 lastName 字段被同时索引和单独索引。

@Entity
@Index(name="EMP_NAME_INDEX", columnNames={"F_NAME","L_NAME"})  // Columns indexed together
public class Employee{
    @Id
    private long id;

    @Index                      // F_NAME column indexed
    @Column(name="F_NAME")
    private String firstName;

    @Index                      // L_NAME column indexed
    @Column(name="L_NAME")
    private String lastName;
    ...
}
于 2013-03-20T21:23:26.623 回答
1

总结其他答案:

我只会选择其中之一。无论如何,它将随 JPA 2.1 一起提供,并且在您确实想要切换 JPA 提供程序的情况下更改应该不会太难。

于 2013-04-08T11:18:33.117 回答
1

OpenJPA 允许您指定非标准注释来定义属性索引。

详情在这里

于 2011-12-16T23:12:01.073 回答
0

使用 JPA 注释是不可能做到这一点的。这是有道理的:在 UniqueConstraint 明确定义业务规则的情况下,索引只是一种使搜索更快的方法。所以这真的应该由 DBA 来完成。

于 2010-08-04T12:57:43.503 回答
0

该解决方案适用于 EclipseLink 2.5,并且可以正常工作(经过测试):

@Table(indexes = {@Index(columnList="mycol1"), @Index(columnList="mycol2")})
@Entity
public class myclass implements Serializable{
      private String mycol1;
      private String mycol2;
}

这假定升序。

于 2013-07-28T21:04:09.507 回答