спящий вопрос о дизайне дао - PullRequest
3 голосов
/ 02 августа 2010

Я хочу создать универсальный DAO для обработки CRUD в моем спящем приложении. Мои сущности имеют большинство ассоциаций как ленивый выбор. Но я считаю, что для того, чтобы спящий режим был максимально эффективным с помощью SELECT, мне нужно создать несколько методов в моих DAO. Вот что я имею в виду:

Сущность A имеет две ассоциации. Иногда я хочу получить эту сущность без загрузки ассоциаций, а иногда я хочу, чтобы она была полностью заполнена, поэтому я бы добавил два метода в DAO:

getWhatever()
getWhateverWithLoadedAssociations()

и у меня будет два разных запроса: один без выборки соединения, а другой с выборкой соединения. В результате hibernate всегда делает один выбор независимо от того, ленив он или нет, потому что я знаю, что я хочу получить сразу.

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

Так это до крайности? Должен ли я просто получить getWhwhat () и просто позволить hibernate сделать другой выбор, когда мне нужны данные для ассоциации, даже если бы я мог спасти от того, что не сделал этот SELECT?

Надеюсь, это не слишком смущает. Я пытаюсь выяснить стоимость количества SELECTS из-за отложенной загрузки и сложности кода

спасибо

Ответы [ 6 ]

2 голосов
/ 02 августа 2010

Так это до крайности?Должен ли я просто использовать getWhwhat () и просто позволить hibernate сделать другой выбор, когда мне нужны данные для ассоциации, даже если бы я мог спасти от того, что не сделал этот SELECT?

Если у вас есть ленивые ассоциации /выборка включена, тогда какая разница, если фрагмент кода, который не нуждается в ассоциации, вызывает getWhatever() или getWhateverWithLoadedAssociations()?Это должно привести к тому же количеству запросов SQL.

Изучите возможности, если у вас есть только один getWhatever() метод:

  1. Кусок кода не имеет доступа к ассоциациям- не запускаются никакие SQL-запросы для загрузки ассоциаций
  2. Часть кода получает доступ к ассоциациям - SQL-запросы для загрузки ассоциаций запускаются.

В любом случае ассоциациязагружается только при необходимости.

Цель отложенной загрузки состоит в том, чтобы вам не приходилось беспокоиться об этом типе вещей - если код, вызывающий метод DAO, обращается к ассоциации, то он загружается;если нет, то это не так.

2 голосов
/ 02 августа 2010

Я думаю, это можно квалифицировать как преждевременную оптимизацию.Другими словами, не делайте этого, если вы точно не знаете, что есть проблема с производительностью.

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

2 голосов
/ 02 августа 2010

Итак, ваша проблема в том, что у вас слишком много методов?Я думаю, что это правильно, потому что эти методы делают разные вещи.

Если вы хотите уменьшить число и используете HQL, вы можете добавить в метод параметр, который говорит, что если вы хотите присоединиться, извлеките отношения:

getWhwhat (Wh whatFetchModef)

, где f может быть логическим значением или объектом, который возвращает HQL-фрагмент строки, который дает вам эти отношения для выборки.

public List<MyObject> getList(boolean fetchProp1) {
         return em.createQuery("select r" +
                "from Object as r " +
                fetchProp1 ? "left join fetch r.prop1 " : "")
                .getResultList();
}

или

public List<MyObject> getList(WhateverFetchMode fetchProp1) {
         return em.createQuery("select r" +
                "from Object as r " +
                fetchProp1.toHql()) // This returns the right join fetch
                .getResultList();
}
1 голос
/ 03 августа 2010

ИМХО, я добавлю несколько следующих методов в общий DAO:

findById(Id id);//lazy load
loadTree(Id id);//load full graph of the entity
load(Id id, String... includePaths);// just load some associations of the entity
0 голосов
/ 02 августа 2010

На мой взгляд, да, вы экстремальный.

Если вы не разрабатываете пакетную процедуру с тысячами этих запросов, нет большой разницы между выполнением одного отдельного запроса и запросами, которые спящий режим выполняет при отложенной загрузке.

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

0 голосов
/ 02 августа 2010

Вы можете иметь общий (в базовом классе) метод dao:

public void initialize(Object entity);

Где вы звоните Hibernate.initialize(entity);

...