SQLExceptionTranslator — це інтерфейс, який має бути реалізований класами, здатними виконувати перетворення між SQLExceptions та власними org.springframework.dao.DataAccessException, які залежать від стратегії доступу до даних. Реалізації можуть бути типізованими (наприклад, використання кодів SQLState для JDBC) або пропрієтарними (наприклад, використання кодів помилок Oracle) для більшої точності.
SQLErrorCodeSQLExceptionTranslator – це реалізація SQLExceptionTranslator, яка використовується за замовчуванням. У цій реалізації використовуються певні коди виробників. Вона більш точна, ніж реалізація SQLState. Перетворення кодів помилок базується на кодах, що зберігаються в класі JavaBean під назвою SQLErrorCodes. Цей клас створюється та заповнюється SQLErrorCodesFactory, яка (як випливає з назви) є фабрикою для створення SQLErrorCodes на основі конфігураційного файлу sql-error-codes.xml. Цей файл заповнюється кодами виробників і ґрунтується на DatabaseProductName, взятому з DatabaseMetaData. Використовуються коди для фактичної бази даних, яку ти використовуєш.
SQLErrorCodeSQLExceptionTranslator застосовує правила узгодження в наступній послідовності:
-
Будь-яке кастомне перетворення, реалізоване підкласом. Зазвичай використовується конкретний
SQLErrorCodeSQLExceptionTranslator, тому це правило не застосовується. Воно застосовується лише в тому випадку, якщо ти дійсно надав реалізацію підкласу. -
Будь-яка кастомна реалізація інтерфейсу
SQLExceptionTranslator, яка надається як властивістьcustomSqlExceptionTranslatorкласуSQLErrorCodes. -
У списку екземплярів класу
CustomSQLErrorCodesTranslation(наданих для властивостіcustomTranslationsкласуSQLErrorCodes) виконується пошук збігу. -
Застосовується зіставлення кодів помилок.
-
Використовується зворотний перетворювач (translator).
SQLExceptionSubclassTranslatorє стандартним перетворювачем. Якщо цей переклад недоступний, наступним поворотним перетворювачем єSQLStateSQLExceptionTranslator.
SQLErrorCodesFactory використовується за замовчуванням для визначення кодів
Error та кастомних перетворень винятків. Вони шукаються у файлі
sql-error-codes.xml з classpath, а відповідний екземпляр
SQLErrorCodes знаходиться на основі імені бази даних із метаданих бази даних, що використовується.
Можна розширити SQLErrorCodeSQLExceptionTranslator, як показано в наступному прикладі:
public class CustomSQLErrorCodesTranslator extends SQLErrorCodeSQLExceptionTranslator {
protected DataAccessException customTranslate(String task, String sql, SQLException sqlEx) {
if (sqlEx.getErrorCode() == -12345) {
return new DeadlockLoserDataAccessException(task, sqlEx);
}
return null;
}
}
class CustomSQLErrorCodesTranslator : SQLErrorCodeSQLExceptionTranslator() {
override fun customTranslate(task: String, sql: String?, sqlEx: SQLException): DataAccessException? {
if (sqlEx.errorCode == -12345) {
return DeadlockLoserDataAccessException(task, sqlEx)
}
return null
}
}
У попередньому прикладі перетворюється конкретний код помилки (-12345), а решта помилок залишається на розсуд стандартної реалізації перетворювача. Щоб використовувати цей кастомний перетворювач, потрібно передати його JdbcTemplate через метод setExceptionTranslator, а потім використовувати цей JdbcTemplate для будь-якої обробки доступу до даних, де цей перетворювач необхідний. У цьому прикладі показано, як можна використовувати цей кастомний перетворювач:
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
// створюємо шаблон JdbcTemplate та встановлюємо джерело даних
this.jdbcTemplate = new JdbcTemplate();
this.jdbcTemplate.setDataSource(dataSource);
// Створюємо кастомний перетворювач і встановлюємо джерело даних для пошуку перетворення за замовчуванням
CustomSQLErrorCodesTranslator tr=new CustomSQLErrorCodesTranslator();
tr.setDataSource(dataSource);
this.jdbcTemplate.setExceptionTranslator(tr);
}
public void updateShippingCharge(long orderId, long pct) {
// використовуємо підготовлений шаблон JdbcTemplate для цього оновлення
this.jdbcTemplate.update("update orders" +
"set shipping_charge = shipping_charge *? / 100" +
" where id = ?", pct, orderId);
}
// створюємо шаблон JdbcTemplate і встановлюємо джерело даних
private val jdbcTemplate = JdbcTemplate(dataSource).apply {
// Створюємо кастомний перетворювач і встановлюємо джерело даних для пошуку перетворення за замовчуванням
exceptionTranslator = CustomSQLErrorCodesTranslator().apply {
this.dataSource = dataSource
}
}
fun updateShippingCharge(orderId: Long, pct: Long) {
// використовуємо підготовлений шаблон JdbcTemplate для цього оновлення
this.jdbcTemplate!!.update("update orders" +
"set shipping_charge = shipping_charge *? / 100" +
" where id = ?", pct, orderId)
}
Кастомному перетворювачу передається джерело даних для пошуку кодів помилок у sql-error-codes.xml.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ