В JPA 2.1 интерфейс StoredProcedureQuery (который расширяет Query) поддерживает хранимые процедуры. В отличие от динамических, именованных или «родных» запросов, этот API-интерфейс позволяет вам вызывать только ту хранимую процедуру, которая уже присутствует в базе данных, но не определять ее. Вы можете вызывать хранимую процедуру с помощью аннотаций (@NamedStoredProcedureQuery) либо динамически.

В листинге 6.30 показана сущность Book, для которой объявляется хранимая процедура sp_archive_books с использованием аннотаций именованных запросов. Аннотация @NamedStoredProcedureQuery определяет имя хранимой процедуры для вызова, типы всех параметров (Date.class и String.class), их соответствующие направления параметров (IN, OUT, INOUT, REF_CURSOR), а также то, как должны быть отображены результирующие наборы (при наличии таковых). Аннотацией @StoredProcedureParameter необходимо снабдить каждый параметр.

Листинг 6.30. Сущность, для которой объявляется именованная хранимая процедура

@Entity

@NamedStoredProcedureQuery(name = "archiveOldBooks", procedureName = 

···························"sp_archive_books",

··parameters = {

····@StoredProcedureParameter(name = "archiveDate", mode = IN, type = Date.class),

····@StoredProcedureParameter(name = "warehouse", mode = IN, 

·····························type = String.class)

··}

)

public class Book {

··@Id @GeneratedValue

··private Long id;

··private String title;

··private Float price;

··private String description;

··private String isbn;

··private String editor;

··private Integer nbOfPage;

··private Boolean illustrations;

··// Конструкторы, геттеры, сеттеры

}

Для вызова хранимой процедуры sp_archive_books вам потребуется прибегнуть к менеджеру сущностей и сгенерировать запрос к именованной хранимой процедуре, передав ее имя (archiveOldBooks). Этот запрос возвратит StoredProcedureQuery, для которого вы сможете задать параметры и выполнить его, как показано в листинге 6.31.

Листинг 6.31. Вызов StoredProcedureQuery

StoredProcedureQuery query = 

em.createNamedStoredProcedureQuery("archiveOldBooks");

query.setParameter("archiveDate", new Date());

query.setParameter("maxBookArchived", 1000);

query.execute();

Если хранимая процедура не определена с использованием метаданных (@NamedStoredProcedureQuery), то вы можете прибегнуть к API-интерфейсу для динамического генерирования запроса к хранимой процедуре. Это означает, что параметры и информацию касаемо результирующего набора потребуется обеспечить программным путем. Это можно сделать с помощью метода registerStoredProcedureParameter интерфейса StoredProcedureQuery, как показано в листинге 6.32.

Листинг 6.32. Регистрация и вызов StoredProcedureQuery

StoredProcedureQuery query = 

em.createStoredProcedureQuery("sp_archive_old_books");

query.registerStoredProcedureParameter("archiveDate", Date.class, ParameterMode.IN);

query.registerStoredProcedureParameter("maxBookArchived", Integer.class, ParameterMode.IN);

query.setParameter("archiveDate", new Date());

query.setParameter("maxBookArchived", 1000);

query.execute();

<p>Cache API</p>

В большинстве спецификаций (а не только в спецификации Java EE) много внимания уделено функциональным требованиям, а нефункциональным требованиям, таким как производительность, масштабируемость или кластеризация, отводится роль деталей реализации. Реализации должны строго придерживаться спецификации, однако также могут привносить свои особенности. Идеальным примером в случае с JPA будет кэширование.

Перейти на страницу:

Похожие книги