Перейти к основному содержимому

Хранимые процедуры с Hibernate

· 5 мин. чтения

Упражнение: Сложение двух чисел

Даны два неотрицательный целых числа в виде непустых связных списков. Их цифры хранятся в обратном порядке. И каждый елемент списка содержить ровно одну цифру. Сложите эти два числа и верните сумму в виде связного списка ...

ANDROMEDA

1. Обзор

Хранимые процедуры — это наборы скомпилированных операторов SQL, находящихся в базе данных. Они используются для инкапсуляции и совместного использования логики с другими программами, а также извлекают выгоду из функций, специфичных для базы данных, таких как подсказки индекса или определенные ключевые слова.

В этой статье показано, как использовать Hibernate для вызова хранимой процедуры в базе данных MySQL .

2. Хранимые процедуры в MySQL

Прежде чем мы обсудим, как вызвать хранимую процедуру из Hibernate, нам нужно ее создать.

Для этого быстрого примера MySQL мы создадим хранимую процедуру для получения всех записей из таблицы foo .

Чтобы создать хранимую процедуру, мы используем оператор CREATE PROCEDURE :

DELIMITER //
CREATE PROCEDURE GetAllFoos()
LANGUAGE SQL
DETERMINISTIC
SQL SECURITY DEFINER
BEGIN
SELECT * FROM foo;
END //
DELIMITER;

Перед оператором BEGIN мы можем определить необязательные операторы. Вы можете углубиться в детали этих утверждений, перейдя по ссылке официальной документации MySQL .

Мы можем использовать оператор CALL , чтобы убедиться, что наша процедура ведет себя желаемым образом:

CALL GetAllFoos();

Теперь, когда наша хранимая процедура запущена и работает, давайте сразу перейдем к тому, как вызывать ее из Hibernate.

3. Вызовите хранимую процедуру с помощью Hibernate

Начиная с Hibernate 3, у нас есть возможность использовать необработанные операторы SQL, включая хранимые процедуры, для запросов к базе данных.

В этом разделе мы рассмотрим, казалось бы, простой пример, который продемонстрирует, как вызвать процедуру GetAllFoos() с помощью Hibernate.

3.1. Конфигурация

Прежде чем мы начнем писать код, который может работать, нам нужно настроить Hibernate в нашем проекте.

И, конечно же, обо всем этом — зависимостях Maven, конфигурации MySQL, конфигурации Hibernate и создании экземпляров SessionFactory — вы можете ознакомиться в статье Hibernate .

3.2. Вызов хранимой процедуры с помощью метода CreateNativeSQL

Hibernate позволяет напрямую выражать запросы в собственном формате SQL . Таким образом, мы можем напрямую создать собственный SQL-запрос и использовать оператор CALL для вызова хранимой процедуры getAllFoos() :

Query query = session.createSQLQuery("CALL GetAllFoos()").addEntity(Foo.class);
List<Foo> allFoos = query.list();

Приведенный выше запрос возвращает список, в котором каждый элемент является объектом Foo o .

Мы используем метод addEntity() для получения объектов сущностей из собственного SQL - запроса, в противном случае ClassCastException будет генерироваться всякий раз, когда хранимая процедура возвращает не необработанное значение.

3.3. Вызов хранимой процедуры с помощью @NamedNativeQueries

Другой способ вызвать хранимую процедуру — использовать аннотацию @NamedNativeQueries .

@NamedNativeQueries используется для указания массива собственных именованных запросов SQL , относящихся к единице сохраняемости:

@NamedNativeQueries({ 
@NamedNativeQuery(
name = "callGetAllFoos",
query = "CALL GetAllFoos()",
resultClass = Foo.class)
})
@Entity
public class Foo implements Serializable {
// Model definition
}

Каждый именованный запрос, очевидно, имеет атрибут name , фактический SQL-запрос и resultClass , который ссылается на сопоставленный объект Foo .

Query query = session.getNamedQuery("callGetAllFoos");
List<Foo> allFoos = query.list();

Атрибут resultClass играет ту же роль, что и метод addEntity() в нашем предыдущем примере.

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

3.4. Вызов хранимой процедуры с помощью @NamedStoredProcedureQuery

Если вы используете JPA 2.1 и реализацию Hibernate EntityManagerFactory и EntityManager .

Аннотацию @NamedStoredProcedureQuery можно использовать для объявления хранимой процедуры:

@NamedStoredProcedureQuery(
name="GetAllFoos",
procedureName="GetAllFoos",
resultClasses = { Foo.class }
)
@Entity
public class Foo implements Serializable {
// Model Definition
}

Чтобы вызвать наш запрос именованной хранимой процедуры, нам нужно создать экземпляр EntityManager, а затем вызвать метод createNamedStoredProcedureQuery() для создания процедуры :

StoredProcedureQuery spQuery = 
entityManager.createNamedStoredProcedureQuery("getAllFoos");

Мы можем напрямую получить список сущностей Foo , вызвав метод execute() для объекта StoredProcedureQuery .

4. Хранимые процедуры с параметрами

Почти всем нашим хранимым процедурам потребуются параметры. В этом разделе мы собираемся показать, как вызывать хранимую процедуру с параметрами из Hibernate .

Давайте создадим хранимую процедуру getFoosByName() в MySQL .

Эта процедура возвращает список объектов Foo , в которых атрибут name соответствует параметру fooName :

DELIMITER //
CREATE PROCEDURE GetFoosByName(IN fooName VARCHAR(255))
LANGUAGE SQL
DETERMINISTIC
SQL SECURITY DEFINER
BEGIN
SELECT * FROM foo WHERE name = fooName;
END //
DELIMITER;

Для вызова процедуры GetFoosByName() будем использовать именованные параметры:

Query query = session.createSQLQuery("CALL GetFoosByName(:fooName)")
.addEntity(Foo.class)
.setParameter("fooName","New Foo");

Точно так же именованный параметр :fooName можно использовать с аннотацией @NamedNativeQuery :

@NamedNativeQuery(
name = "callGetFoosByName",
query = "CALL GetFoosByName(:fooName)",
resultClass = Foo.class
)

Именованный запрос будет вызываться следующим образом:

Query query = session.getNamedQuery("callGetFoosByName")
.setParameter("fooName","New Foo");

При использовании аннотации @NamedStoredProcedureQuery мы можем указать параметры с помощью аннотации @StoredProcedureParameter :

@NamedStoredProcedureQuery(
name="GetFoosByName",
procedureName="GetFoosByName",
resultClasses = { Foo.class },
parameters={
@StoredProcedureParameter(name="fooName", type=String.class, mode=ParameterMode.IN)
}
)

Мы можем использовать метод setParameter() для вызова нашей хранимой процедуры с параметром fooName :

StoredProcedureQuery spQuery = entityManager.createNamedStoredProcedureQuery("GetFoosByName")
.setParameter("fooName", "NewFooName");

5. Вывод

В этой статье показано , как использовать Hibernate для вызова хранимой процедуры в базе данных MySQL с использованием различных подходов.

Стоит отметить, что не все СУБД поддерживают хранимые процедуры .

Вы можете ознакомиться с примерами, представленными в этой статье, в связанном проекте GitHub .