Ответ
Да, работал с хранимыми процедурами. Это предкомпилированные блоки SQL-кода, хранящиеся на стороне СУБД.
Преимущества:
- Производительность: План выполнения кэшируется СУБД.
- Снижение сетевого трафика: Вместо нескольких запросов отправляется один вызов.
- Безопасность и абстракция: Клиентскому коду не видна структура таблиц, можно контролировать доступ.
- Централизация логики: Изменения вносятся в одном месте (БД).
Недостатки:
- Привязка к вендору: Синтаксис отличается между PostgreSQL, Oracle, MySQL.
- Сложность отладки и тестирования.
- Может нарушать принцип разделения ответственности, если содержит сложную бизнес-логику.
Вызов из Java с использованием JDBC (CallableStatement):
// Процедура: CREATE PROCEDURE get_employee(IN emp_id INT, OUT emp_name VARCHAR(255))
String sql = "{call get_employee(?, ?)}"; // Синтаксис вызова
try (Connection conn = dataSource.getConnection();
CallableStatement stmt = conn.prepareCall(sql)) {
// Установка входных (IN) параметров
stmt.setInt(1, employeeId);
// Регистрация выходных (OUT) параметров
stmt.registerOutParameter(2, Types.VARCHAR);
// Выполнение процедуры
stmt.execute();
// Получение значения выходного параметра
String employeeName = stmt.getString(2);
System.out.println("Employee: " + employeeName);
} catch (SQLException e) {
// Обработка ошибок
}
Вызов через JPA (Hibernate):
@PersistenceContext
private EntityManager entityManager;
StoredProcedureQuery query = entityManager
.createStoredProcedureQuery("get_employee")
.registerStoredProcedureParameter(1, Integer.class, ParameterMode.IN)
.registerStoredProcedureParameter(2, String.class, ParameterMode.OUT)
.setParameter(1, employeeId);
query.execute();
String employeeName = (String) query.getOutputParameterValue(2);
Когда использовать: Для сложных атомарных операций с данными, критичных по производительности, или когда логика должна быть доступна для разных приложений, работающих с одной БД.