Указание индекса (неуникальный ключ) с использованием JPA - PullRequest
80 голосов
/ 04 августа 2010

Как определить поле, например, 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 запрещена для этого местоположения

Ответы [ 11 ]

173 голосов
/ 26 марта 2014

С 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{
30 голосов
/ 15 апреля 2015

Уникальная отобранная коллекция аннотаций индекса

= Технические характеристики =

  • JPA 2.1+: javax.persistence.Index (или см. JSR-000338 PDF, стр. 452, позиция 11.1.23)
    Аннотация JPA @Index может использоваться только как часть другой аннотации, например @Table, @SecondaryTable и т. д.: * 10101 *

    @Table(indexes = { @Index(...) })
    
  • JDO 2.1+: javax.jdo.annotations.Index

= ORM Каркасы =

= ORM для Android =

= Другое (сложно классифицировать) =

  • Область - Альтернативная БД для iOS / Android: Аннотация io.realm.annotations.Index;
  • Empire-db - легкий, но мощный слой абстракции реляционной БД на основе JDBC.У него нет определения схемы с помощью аннотаций;
  • Kotlin NoSQL (GitHub) - реактивный и типобезопасный DSL для работы с базами данных NoSQL (PoC): ???
  • Slick - Реактивное функционально-реляционное отображение для Scala.У него нет определения схемы с помощью аннотаций.

Просто выберите одну из них.

29 голосов
/ 05 апреля 2013

В JPA 2.1 (наконец-то) добавлена ​​поддержка индексов и внешних ключей!См. этот блог для деталей.JPA 2.1 является частью Java EE 7, который вышел.

Если вам нравится жить на краю, вы можете получить последний снимок для eclipselink из их maven репозитория (groupId: org.eclipse.persistence, artifactId: eclipselink, версия: 2.5.0-SNAPSHOT).Только для аннотаций JPA (которые должны работать с любым провайдером, если они поддерживают 2.1) используйте artifactID: javax.persistence, версия: 2.1.0-SNAPSHOT.

Я использую его для проекта, который не будетбыть законченным до его выпуска, и я не заметил никаких ужасных проблем (хотя я не делаю с этим ничего слишком сложного).

ОБНОВЛЕНИЕ (26 сентября 2013 г.): в настоящее время выпускают и выпускают версии-кандидатыeclipselink доступны в центральном (главном) репозитории, поэтому вам больше не нужно добавлять репозиторий eclipselink в проекты Maven.Последняя версия выпуска 2.5.0, но 2.5.1-RC3 также присутствует.Я бы переключился на 2.5.1 как можно скорее из-за проблем с выпуском 2.5.0 (модель не работает).

7 голосов
/ 16 октября 2014

В 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 индекса:

  • уникальный индекс на первичномидентификатор ключа

  • индекс для AGE

  • составной индекс для FNAME, SNAME

Примечание 1:Составной индекс вы получаете, имея две аннотации @Index с одинаковыми именами

Примечание 2: вы указываете имя столбца в columnList, а не fieldName

5 голосов
/ 04 августа 2010

Мне бы очень хотелось иметь возможность задавать индексы базы данных стандартизированным способом, но, к сожалению, это не является частью спецификации JPA (возможно, потому что поддержка генерации DDL не требуется в спецификации JPA, которая является своего родадорожный блок для такой функции).

Так что вам придется полагаться на расширение, специфичное для провайдера.Hibernate, OpenJPA и EclipseLink явно предлагают такое расширение.Я не могу подтвердить для DataNucleus, но так как определение индексов является частью JDO, я предполагаю, что это так.не вижу веской причины не включать такую ​​вещь в JPA (тем более что база данных не всегда находится под вашим контролем) для оптимальной поддержки генерации DDL.

Кстати, я предлагаю скачать спецификацию JPA 2.0.

4 голосов
/ 04 августа 2010

Насколько я знаю, нет перекрестного способа JPA-провайдера для указания индексов.Однако вы всегда можете создать их вручную непосредственно в базе данных, большинство баз данных получат их автоматически при планировании запросов.

2 голосов
/ 21 марта 2013

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;
    ...
}
1 голос
/ 08 апреля 2013

Подводя итог другим ответам:

Я бы просто пошел за одним из них. В любом случае, он будет поставляться с JPA 2.1, и его не должно быть слишком сложно изменить, если вы действительно хотите сменить провайдера JPA.

1 голос
/ 17 декабря 2011

OpenJPA позволяет вам указать нестандартную аннотацию для определения индекса для свойства.

Подробности: здесь .

0 голосов
/ 29 июля 2013

Это решение для EclipseLink 2.5, и оно работает (проверено):

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

Это предполагает восходящий порядок.

...