1. Обзор
Эта статья покажет, как реализовать DAO с помощью Spring и Hibernate . Базовую конфигурацию Hibernate см. В статьях о Hibernate 3 и Hibernate 4 с Spring.
2. Больше нет весенних шаблонов
Начиная с Spring 3.0 и Hibernate 3.0.1, Spring HibernateTemplate больше не требуется для управления сеансом Hibernate. Теперь можно использовать контекстные сеансы — сеансы, управляемые непосредственно Hibernate и активные в рамках транзакции.
Как следствие, в настоящее время рекомендуется использовать непосредственно API Hibernate вместо HibernateTemplate , что эффективно полностью отделит реализацию уровня DAO от Spring.
2.1. Перевод исключений без HibernateTemplate — жив и здоров
Перевод исключений был одной из обязанностей HibernateTemplate — перевод исключений Hibernate низкого уровня в общие исключения Spring более высокого уровня.
Без шаблона этот механизм по-прежнему включен и активен для всех DAO, аннотированных аннотацией @Repository . В этом случае используется постпроцессор bean-компонента Spring, который будет консультировать все bean- компоненты @Repository со всем PersistenceExceptionTranslator, найденным в контексте Spring.
Следует помнить, что трансляция исключений осуществляется через прокси-серверы; чтобы Spring мог создавать прокси вокруг классов DAO, они не должны быть объявлены как final .
2.2. Управление Hibernate Session без шаблона
Когда появилась поддержка Hibernate для контекстных сессий, HibernateTemplate по сути устарел; фактически, javadoc класса был обновлен с этим советом (выделенный жирным шрифтом из оригинала)
ПРИМЕЧАНИЕ. Начиная с Hibernate 3.0.1, транзакционный код доступа Hibernate также можно кодировать в простом стиле Hibernate. Следовательно, для новых проектов рассмотрите возможность принятия стандартного стиля кодирования объектов доступа к данным в стиле Hibernate3, основанного на {@link org.hibernate.SessionFactory # getCurrentSession ()}.
3. ДАО
Начнем с базового DAO — абстрактного параметризованного DAO, который поддерживает общие общие операции и предназначен для расширения для каждого объекта:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
public abstract class AbstractHibernateDAO< T extends Serializable >{ private Class< T > clazz; @Autowired private SessionFactory sessionFactory; public void setClazz( final Class< T > clazzToSet ){ clazz = clazzToSet; } public T findOne( final long id ){ return (T) getCurrentSession().get( clazz, id ); } public List< T > findAll(){ return getCurrentSession() .createQuery( "from " + clazz.getName() ).list(); } public void save( final T entity ){ getCurrentSession().persist( entity ); } public T update( final T entity ){ return (T) getCurrentSession().merge( entity ); } public void delete( final T entity ){ getCurrentSession().delete( entity ); } public void deleteById( final long id ){ final T entity = findOne( id); delete( entity ); } protected final Session getCurrentSession(){ return sessionFactory.getCurrentSession(); } } |
Здесь интересно несколько аспектов — как уже говорилось, абстрактный DAO не расширяет какой-либо шаблон Spring (например, HibernateTemplate ). Вместо этого Hibernate SessionFactory внедряется непосредственно в DAO и будет играть роль основного Hibernate API через контекстный сеанс, который он предоставляет:
this.sessionFactory. getCurrentSession ();
Также обратите внимание, что класс сущности передается в конструкторе для использования в общих операциях.
Теперь давайте рассмотрим пример реализации этого DAO для объекта Foo :
1
2
3
4
5
6
7
|
@Repository public class FooDAO extends AbstractHibernateDAO< Foo > implements IFooDAO{ public FooDAO(){ setClazz(Foo. class ); } } |
4. Вывод
В этой статье рассказывается о настройке и реализации уровня персистентности в Hibernate и Spring 3.1 с использованием конфигурации на основе XML и Java.
Обсуждались причины прекращения использования шаблонов для уровня DAO, а также возможные подводные камни при настройке Spring для управления транзакциями и сеансом Hibernate. Конечный результат — легкая, чистая реализация DAO, практически не зависящая от времени компиляции с Spring.
Реализацию этого простого проекта можно найти в проекте github — это проект на основе Eclipse, поэтому его легко импортировать и запускать как есть.