Підтримка об'єкта доступу до даних (Data Access Object/DAO) у Spring спрямована на спрощення роботи з технологіями доступу до даних (таких як JDBC, Hibernate або JPA). Це дозволяє легко перемикатися між вищезазначеними технологіями підтримки постійного зберігання, а також не перейматися перехопленням винятків, характерних для кожної технології.
Узгоджена ієрархія винятків
Spring забезпечує зручний перехід від специфічних для технології винятків, таких як SQLException
, до
власної ієрархії класів винятків, у якій кореневим винятком є DataAccessException
. Ці винятки огортають
вихідний виняток, тому відсутній ризик того, що ти можеш втратити інформацію про те, що могло піти не так.
На додаток до винятків JDBC, Spring також може огорнути специфічні винятки JPA та Hibernate, перетворюючи їх на набір організованих винятків часу виконання. Це дозволяє обробляти більшість невідновлюваних винятків постійного зберігання лише на відповідних рівнях, не вдаючись до стереотипних блоків "catch-and-throw" та оголошень винятків у ваших DAO. (Однак ти все одно можеш відловлювати та обробляти винятки скрізь, де це необхідно). Як згадувалося вище, винятки JDBC (включно з діалектами, специфічними для баз даних) також перетворюються на ту саму ієрархію, що означає, що ти можеш виконувати деякі операції з JDBC в межах моделі узгодженого програмування.
Попереднє пояснення справедливе і щодо різних класів шаблонів у засобах підтримки Spring для різних ORM-фреймворків.
Якщо ти використовуєш класи на основі перехоплювачів, програма повинна сама займатися обробкою HibernateExceptions
та PersistenceExceptions
, переважно делегуючи її методам
convertHibernateAccessException(..)
або convertJpaAccessException(..)
утиліти SessionFactoryUtils
відповідно. Ці методи перетворюють винятки на такі, що сумісні з винятками в ієрархії винятків org.springframework.dao
.
Оскільки PersistenceExceptions
неперевірені, вони також можуть бути згенеровані (щоправда, жертвуючи
типізованою абстракцією DAO у плані винятків).
На наступному зображенні показано ієрархію винятків, яку пропонує Spring. (Зверни увагу, що ієрархія класів, подана
на малюнку, показує лише частину всієї ієрархії DataAccessException
).
Анотації, що використовуються для налаштування класів DAO або репозиторію
Найкращий спосіб забезпечити те, щоб ваші об'єкти доступу до даних (DAO) або репозиторії гарантовано перетворювали
(транслювали) винятки, — використовувати анотацію @Repository
. Ця анотація також дозволяє засобам
підтримки сканування компонентів знаходити та налаштовувати DAO та репозиторії без необхідності надавати для них
XML-записи конфігурації. У цьому прикладі показано, як використовувати анотацію @Repository
:
@Repository
public class SomeMovieFinder implements MovieFinder {
// ...
}
- Анотація
@Repository
.
@Repository
class SomeMovieFinder : MovieFinder {
// ...
}
- Анотація
@Repository
.
Будь-якій реалізації DAO або репозиторію потрібен доступ до ресурсу постійного зберігання, залежно від технології
постійного зберігання, що використовується. Наприклад, репозиторію на основі JDBC необхідний доступ до DataSource
з JDBC, а сховищу на основі JPA — доступ до EntityManager
. Найпростіший спосіб досягти цього —
впровадити залежність ресурсу за допомогою однієї з анотацій @Autowired
, @Inject
, @Resource
або @PersistenceContext
. Наступний приклад є робочим щодо репозиторію JPA:
@Repository
public class JpaMovieFinder implements MovieFinder {
@PersistenceContext
private EntityManager entityManager;
// ...
}
@Repository
class JpaMovieFinder : MovieFinder {
@PersistenceContext
private lateinit var entityManager: EntityManager
// ...
}
Якщо використовуються класичні API-інтерфейси Hibernate, можна впровадити SessionFactory
, як показано в
наступному прикладі:
@Repository
public class HibernateMovieFinder implements MovieFinder {
private SessionFactory sessionFactory;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
// ...
}
@Repository
class HibernateMovieFinder(private val sessionFactory: SessionFactory) : MovieFinder {
// ...
}
Останній приклад, який ми продемонструємо, стосується типового засобу підтримки JDBC. DataSource
можна
впровадити в метод ініціалізації або конструктор, де ти створиш JdbcTemplate
та інші класи підтримки
доступу до даних (такі як SimpleJdbcCall
тощо), використовуючи цей DataSource
. У
наступному прикладі виконується автоматичне виявлення та зв'язування DataSource
:
@Repository
public class JdbcMovieFinder implements MovieFinder {
private JdbcTemplate jdbcTemplate;
@Autowired
public void init(DataSource dataSource) {
this.jdbcTemplate = новий JdbcTemplate(dataSource);
}
// ...
}
@Repository
class JdbcMovieFinder(dataSource: DataSource) : MovieFinder {
private val jdbcTemplate = JdbcTemplate(dataSource)
// ...
}
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ