如何定义一个字段,例如email
具有使用JPA注释的索引。我们在email
上需要一个non-unique密钥,因为这个字段每天都有数以百万计的查询,并且没有密钥有点慢。
@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;
}
我已经看到了一个hibernate特定的注释,但是我正在尝试避免供应商的具体解决方案,因为我们仍然在hibernate和datanucleus之间作出决定。
更新:
从JPA 2.1开始,您可以做到这一点。参见:The annotation @Index is disallowed for this location
据我所知,没有一个指定索引的cross-JPA-Provider方式。但是,您可以随时直接在数据库中创建它们,大多数数据库将在查询计划期间自动选择它们。
使用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{
JPA 2.1(最后)增加了索引和外键的支持!有关详细信息,请参阅this blog。 JPA 2.1是Java EE 7的一部分。
如果您喜欢生活在边,您可以从他们的maven repository(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版本的问题(模型源不起作用),我将切换到2.5.1 ASAP。
JPA 2.1+:javax.persistence.Index
(或参见JSR-000338,第450页,第11.1.23条)JPA @Index
注释只能用作另一注释的一部分,如@Table
,@SecondaryTable
等。
@Table(indexes = { @Index(...) })
JDO 2.1+:javax.jdo.annotations.Index
♥Hibernate ORM:org.hibernate.annotations.Index
;
OpenJPA:org.apache.openjpa.persistence.jdbc.Index
;
EclipseLink:org.eclipse.persistence.annotations.Index
;
DataNucleus:org.datanucleus.api.jpa.annotations.Index
;
Carbonado (GitHub):com.amazon.carbonado.Index
;
EBean:com.avaje.ebean.annotation.Index
;
Ujorm:注释org.ujorm.orm.annot.Column
,index
和uniqueIndex
性质;
请求(GitHub):注释io.requery.Index
;
Exposed(Kotlin SQL Library):org.jetbrains.exposed.sql.Index,org.jetbrains.exposed.sql.Table#index()。例:
object Persons : IdTable() {
val code = varchar("code", 50).index()
}
♥ActiveAndroid:注释com.activeandroid.annotation.Column
具有index
,indexGroups
,unique
和uniqueGroups
性质;
ORMLite:注释com.j256.ormlite.field.DatabaseField
具有index
性质;
greenDAO:de.greenrobot.daogenerator.Index
;
ORMAN (GitHub):org.orman.mapper.annotation.Index
;
★DBFlow (GitHub):com.raizlabs.android.dbflow.sql.index.Index
(example的用法);
other。
Realm – iOS /Android的备用数据库:注释io.realm.annotations.Index
;
Empire-db – 一个基于JDBC的轻量级但强大的关系数据库抽象层。它通过注释没有模式定义;
Kotlin NoSQL (GitHub) – 用于与NoSQL数据库(PoC)一起工作的反应性和type-safe DSL:?
只要去其中一个。
我真的希望能够以标准化的方式指定数据库索引,但可惜的是,这不是JPA规范的一部分(可能是因为JPA规范不需要DDL生成支持,这是JPA规范中的一种路径这样的特征)。
所以你必须依赖一个提供者特定的扩展。 Hibernate,OpenJPA和EclipseLink清楚地提供了这样的扩展。我无法确认DataNucleus,但由于索引定义是JDO的一部分,我猜这是。
我真的希望索引支持将在下一个版本的规范中得到标准化,从而不同意其他答案,我没有看到有什么好的理由不在JPA中包含这样的事情(特别是因为数据库并不总是在你的控制之下)以获得最佳的DDL生成支持。
顺便说一下,我建议下载JPA 2.0规范。
在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
==============================================================
可以为空、精度15位、保留2位小数
@
Column
(nullable =
true
,
precision
= 15, scale = 2)
private BigDecimal xxxx;