Grigor60
@Grigor60
Luxoft java Developer

Лучшая практика DAO в Hibernate: почему всегда нужно писать как можно меньше запросов(query)?

Вовремя code review возник конфликт как правильнее сделать запрос. Решили спросить 3-ю сторону.

Запрос состоит из нескольких Entity. некоторые из которых являються условием.
предложение номер 1: загрузить сначала Entity для условий, a потом подать их во второй запрос.
public ProviderMapped findByProviderId(final String providerId) {
 		Criteria c = getSession().createCriteria(ProviderMapped.class);
		c.setCacheable(true);
 		c.add(Restrictions.eq("providerId", providerId)); 
 		return (ProviderMapped) c.uniqueResult();
}

public Collection<BusinessRuleAppliedMarginByClientMarginClassMapped> findAllByProvider(final ProviderMapped provider) {
		Criteria criteria = getSession().createCriteria(getPersistentClass());
		criteria.add(Restrictions.eq("provider", provider));
		return criteria.list();
}

предложение номер 2: сделать все в 1 query.
public Collection<BusinessRuleAppliedMarginByClientMarginClassMapped> findAllByProvider(Providerid providerId) {
		Criteria criteria = getSession().createCriteria(getPersistentClass());
		criteria.add(Restrictions.eq("provider.id", providerId.getId));
		return criteria.list();
}

исходный код по максимум упрощен что бы не смушать нашей бизнес логикой.

Важное примечаение: если включить логи в hibernate то мы увидим что во втором случае hibernate все равно сделать два SQl запроса. providerMapped обычно кешируеться.

Вопрос! какие есть аргументы за и против?
  • Вопрос задан
  • 3843 просмотра
Пригласить эксперта
Ответы на вопрос 1
@bobzer
Java EE Developer
Столько всего можно сказать, что аж пальцы разбегаются.

Во-первых, классика - не занимайтесь преждевременной оптимизацией. Вы ведь сделали замеры расхода ресурсов, перед тем как оптимизировать? Этот запрос хотя бы пару раз в секунду выполняется, не реже, нет? Вы ведь точно уверены, что именно это место "жрет" не менее 20% времени от общего времени обработки процесса? И вы ведь в курсе о том, что любые программные кеши - ничто в сравнении с тем, как умеет кешировать любая "приличная" СУБД?

Во-вторых - построение HQL-запросов. Насколько мне известно, для One-To-Many нет разницы между сущностью и её ID. Вы замапили сущность, а не её ID, получив возможность доступа к объекту целиком при вычитывании из БД. Но это вам не мешает использовать просто ID при указании критериев выборки. Вам вовсе не нужно читать сущность из БД прежде чем передать ее в HQL-запрос, т.к. Hibernate-у не нужна сущность целиком, он всё равно "возьмет" лишь ID. Т.е., у вас есть ID, но в маппинге указана сущность - в HQL можно передать эмуляцию - создать new Proveder(), указать ему ID и передать в HQL объект Proveder без чтения его из БД.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы