Получение правильного шаблона Hibernate в универсальном Spring CRUD DAO - PullRequest
0 голосов
/ 16 сентября 2009

Я все еще новичок в Spring, и я считаю, что это раздражает создание всех этих CRUD DAO, поэтому я сделал «открытый класс GenericCRUDDAO, расширяющий HibernateDaoSupport, реализующий CRUDDAO». В своих сервисных объектах я просто говорю что-то вроде

private GenericCRUDDAO<User, Integer> userDAO = new GenericCRUDDAO<User, Integer>();

и больше мне не нужно писать простые DAO и подключать их. Ура! За исключением одной вещи, я уверен, что все, что вы, опытные разработчики Spring, видите сразу: я не могу получить шаблон Hibernate внутри GenericCRUDDAO, поэтому я делаю

HibernateTemplate ht = getHibernateTemplate();

дает мне ноль. Не так хорошо, как хотелось бы. Я думал о его подключении, то есть создании универсального bean-компонента CRUDDAO и последующей установки статического AnnotationSessionFactoryBean, но это все равно не дало бы мне HibernateTemplate. Любые предложения о том, как мне обойти это, чтобы я мог иметь свой шаблон Hibernate?

Есть ли еще какие-то проблемы с созданием универсального CRUD DAO, о котором я должен подумать?

Приветствия

Nik

Ответы [ 2 ]

4 голосов
/ 16 сентября 2009

Для многих HibernateTemplate и HibernateDaoSupport находятся на выходе, и вместо этого предпочтительнее вводить SessionFactory. Не все, заметьте, но это тенденция, которую я принял не так давно, убрав HibernateTemplate из моего собственного универсального DAO.

Этот блог содержит довольно хорошее резюме.

Примеры автора должны помочь вам добраться туда, куда вы хотите.

1 голос
/ 16 сентября 2009

GenericDao

Ну, для меня, если ваш GenericDAO является «универсальным», то вам может понадобиться только один экземпляр , и делать все с этим единственным экземпляром.

Я уверен, что вас не беспокоит, например, в связи с повторением, вы злитесь (и я с вами согласен).

Например, вы можете передать класс Entity универсальному методу .

  • public void save (Class, E ...): позволяет сохранить один или несколько экземпляров типа E, где E является одним из ваших объектов.
  • public E load (Class, Long id): загружает объект.
  • ...

    /** Assuming the entities have a superclass SuperEntity with getIdent(). */
    public class GenericDaoImpl implements GenericDao {
    
       /** Save a bunch of entities */
       public void save(SuperEntity... entities) {
         for(SuperEntity entity : entities) {
           getSession().save(entity);
         }
       }
    
       /** Load any entity. */
       public <E extends SuperEntity> E load(Class<E> entityClass, Long ident) {
         return (E)getSession().load(entityClass, ident);
       }
    
       // other generic methods
    }
    

Вариант

В наших приложениях у нас фактически есть вариант для этого. Поскольку у нас много специфических запросов для каждого Дао, нам все равно нужны определенные классы Дао (создайте класс и подключите его), поэтому, чтобы избежать особого случая Дао, который не будет определен, мы сразу создадим определенные классы Дао.

Кодирование

Но мы никоим образом не повторяем код. Все наши Daos расширяют GenericDao, предоставляя в конструкторе необходимый параметр Class. Пример кода (не полный, простой, чтобы понять основную идею):

    public abstract class GenericDaoImpl<E extends SuperEntity> 
        implements GenericDao<E> {

       /** Available for generic methods, so it is not a parameter 
        * for the generic methods. */
       private final Class<E> entityClass;

       protected GenericDaoImpl(Class<E> entityClass) {
         this.entityClass = entityClass;
       }

       // generic implementation ; can be made efficient, as it may 
       // send the orders as a batch
       public void save(E... entities) {
         for(SuperEntity entity : entities) {
           getSession().save(entityClass, entity.getIdent());
         }
         // possibly add flushing, clearing them from the Session ...
       }

       // other generic methods
    }

    public class PersonDaoImpl extends GenericDaoImpl<Person> 
        implements PersonDao {

      /** Constructor, instanciating the superclass with the class parameter. */
      public PersonDaoImpl() {
        super(Person.class);
      }

      /** Specific method. */
      public List<Person> findByAge(int minAge, int maxAge) {
        //....
      }
    }

Электропроводка

Соединение всех бобов не смертельно. В настоящее время существует множество политик автоматического подключения, вам не нужно об этом беспокоиться. Увидимся весной
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-annotation-config

...