Hibernate - ORM, JPA, JPQL

ORM (Object-Relational Mapping, объектно-реляционное отображение) — технология программирования, которая связывает базы данных с концепциями объектно-ориентированных языков программирования. В объектно-ориентированном программировании объекты приложения представляют объекты реального мира. ORM предназначена для преобразования объектов в форму для их сохранения в файлах или базах данных, а также их дальнейшего извлечения в программе с сохранением свойств объектов и отношений между ними. Такие объекты называют «хранимыми» (persistent). ORM освобождает программиста от работы с SQL-скриптами и позволяет сосредоточиться на ООП.

В программе основой ORM является конфигурационный файл, в котором описывается порядок хранения объекта в БД. Если с обычными полями все прозрачно : строковое поле записывается в колонку с типом varchar, а целочисленное - в int, то со связями между объектами все гораздо интересней. Например, в программе используются классы "Город" и "Улица". Для обоих классов созданы конфигурационные файлы, в которых описаны их поля и связи с таблицами БД. Но кроме этого "Улица" имеет ссылку на "Город". В таком случае таблицы в БД будут связаны по внешнему ключу, что также должно быть описано в одном из конфигурационных файлов.

JPA - Java Persistence API, javax.persistence

Для сохранения Java-объектов в базе данных и чтения из БД следует использовать JPA. JPA (Java Persistence API) — программный интерфейс API, входящий с версии Java 5 в состав платформ Java SE и Java EE. Существует несколько реализаций интерфейса JPA, среди которых наиболее популярным является Hibernate.

Непосредственно JPA представлен в пакете javax.persistence и включает платформо-независимый объектно-ориентированный язык запросов JPQL.

JPA оперирует таким понятием, как сущность Entity, которая является POJO-классом и связана с БД с помощью аннотации @Entity или через файл конфигурации XML. К такому классу предъявляются следующие требования :

  • наличие пустого public или protected конструктора;
  • не должен быть вложенным, являться интерфейсом или enum;
  • не должен быть final и не должен содержать final-свойств;
  • должен включать хотя бы одно @Id-поле.

При этом сущность может иметь непустые конструкторы, наследоваться или быть наследованной, содержать методы, не связанные со свойствами (методы get/set), и реализовывать интерфейсы. Entities могут быть связаны друг с другом (один-к-одному, один-ко-многим, многие-к-одному и многие-ко-многим).

Примеры сущностей Entity

В самом простом виде (без методов определения и получения значения свойств) JPA сущности можно представить следующим образом :

@Entity
public class Author {
    @Id
    private Integer id;
    private String firstName;
    private String lastName;
    
    @ManyToMany
    private List<Book> books;
}

@Entity
public class Book {
    @Id
    private Integer id;
    private String title;
    private String isbn;
    
    @ManyToOne
    private Publisher publisher;
    
    @ManyToMany
    private List<Author> authors;
}

@Entity
public class Publisher {
    @Id
    private Integer id;
    private String name;
    private String address;

    @OneToMany(mappedBy = "publisher")
    private List<Book> books;
}

JPQL - Java Persistence Query Language

Java Persistence Query Language (JPQL) — платформо-независимый объектно-ориентированный язык запросов являющийся частью спецификации JPA.

JPQL используется для написания запросов к сущностям, хранящимся в реляционной базе данных. JPQL во многом похож на SQL, но в отличие от последнего, оперирует запросами, составленными по отношению к сущностям JPA, в отличие от прямых запросов к таблицам базы данных. В дополнение к получению объектов (запросы SELECT), JPQL поддерживает запросы, основанные на операторах UPDATE и DELETE. JPA реализует концепцию ORM.

JPQL основан на Hibernate Query Language (HQL), более раннем не стандартизованном языке запросов, включённом в библиотеку объектно-реляционного отображения Hibernate. Hibernate и HQL были созданы до появления спецификации JPA. JPQL является подмножеством языка запросов HQL.

Примеры JPQL

JPQL запрос получения списка авторов сущности "Author", упорядоченных в алфавитном порядке, имеет вид :

SELECT a FROM Author a ORDER BY a.firstName, a.lastName

Запрос получения списка авторов, когда-либо опубликованных издательством «Publisher Press» :

SELECT DISTINCT a FROM Author a 
  INNER JOIN a.books b WHERE 
     b.publisher.name = 'Publisher Press'
JPQL поддерживает именованные параметры, которые начинаются с символа двоеточия ':'. Следующая функция, возвращающая список авторов с определенной фамилией, будет иметь следующий вид :
import javax.persistence.Query;
import javax.persistence.EntityManager;

import org.apache.commons.lang.StringUtils;

...

@SuppressWarnings("unchecked")
public List<Author< getAuthorsByLastName(String lastName)
{
    String queryString = "SELECT a FROM Author a " +
                         "WHERE LOWER(a.lastName) = :lastName";
    Query query = getEntityManager().createQuery(queryString);
    
    query.setParameter("lastName", StringUtils.lowerCase(lastName));
    return query.getResultList();
}
  Рейтинг@Mail.ru