Есть ли более эффективный способ разбивки на страницы в Hibernate, чем выполнение запросов select и count?

Как кто-то может захотеть использовать одно и то же приложение через два или более проектов с базой данных по многим причинам, и поэтому получите эту ошибку, я здесь рассматриваю этот конкретный сценарий. Самый простой способ запуска одного и того же приложения на двух или более различных проектах firebase (скажем, производства и постановки) заключается в добавлении к вашему модулю уровня build.gradle файла варианта сборки (скажем, постановки), такого как:

apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.firebase-perf'

android {
    compileSdkVersion 27
    buildToolsVersion "27.0.3"
    defaultConfig {
        applicationId "com.mydomain.myapp"
        minSdkVersion 19
        targetSdkVersion 27
        versionCode 18
        versionName "2.8"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        staging {
            initWith debug
            applicationIdSuffix ".staging"
            versionNameSuffix = "-staging"
        }
    }
}

dependencies {
    [...]
}

// Firebase
apply plugin: 'com.google.gms.google-services'

В варианте сборки staging наиболее важна строка:

applicationIdSuffix ".staging"

Это приведет к тому, что во время сборки будет добавлен суффикс «.staging» к вашему идентификатору приложения, чтобы вы автоматически have

applicationId "com.mydomain.myapp.staging"

Вам нужно добавить это приложение ("com.mydomain.myapp.staging") в проект промежуточной подготовки Firebase, и вы сможете добавить в это приложение тот же "com.mydomain.myapp" SHA1, потому что он имеет другой идентификатор приложения.

37
задан serg 3 October 2008 в 17:50
поделиться

8 ответов

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

5
ответ дан Kyle Dyer 3 October 2008 в 17:50
поделиться

Существует путь

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
    -> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();

, второй ВЫБОР возвращает число, указывающее, сколько строк, которые возвратил бы первый ВЫБОР, имело записанный без ПРЕДЕЛЬНОГО пункта.

Ссылка: FOUND_ROWS ()

2
ответ дан michal kralik 3 October 2008 в 17:50
поделиться

вот способ, которым выполняют в разбиении на страницы, в спящем режиме

Query q = sess.createQuery("from DomesticCat cat");
q.setFirstResult(20);
q.setMaxResults(10);
List cats = q.list();

, можно добраться, больше информации от в спящем режиме документы в: http://www.hibernate.org/hib_docs/v3/reference/en-US/html_single/#objectstate-querying-executing-pagination 10.4.1.5 и 10.4.1.6 раздела дают Вам больше flexbile опций.

BR,
~A

-4
ответ дан anjanb 3 October 2008 в 17:50
поделиться

Baron Schwartz по MySQLPerformanceBlog.com создал сообщение об этом. Мне жаль, что не было чудодейственного средства для этой проблемы, но нет. Сводка опций он представил:

  1. На первом запросе, выборке и кэше все результаты.
  2. не показывают все результаты.
  3. не показывают общее количество или промежуточные каналы к другим страницам. Покажите только "следующую" ссылку.
  4. Оценка, сколько там результаты.
11
ответ дан Eric R. Rath 3 October 2008 в 17:50
поделиться
  • 1
    Зависит от Вашего сценария, я думаю. Вы можете также " derive" стиль от Кнопки на панели инструментов разрабатывает при помощи Стиля. Свойство BasedOn. – Kent Boogaart 30 March 2009 в 15:11

Можно использовать MultiQuery для выполнения обоих запросов в вызове единой базы данных, который намного более эффективен. Можно также генерировать запрос количества, таким образом, Вы не должны писать ему каждый раз. Вот общее представление...

var hql = "from Item where i.Age > :age"
var countHql = "select count(*) " + hql;

IMultiQuery multiQuery = _session.CreateMultiQuery()
    .Add(s.CreateQuery(hql)
            .SetInt32("age", 50).SetFirstResult(10))
    .Add(s.CreateQuery(countHql)
            .SetInt32("age", 50));

var results = multiQuery.List();
var items = (IList<Item>) results[0];
var count = (long)((IList<Item>) results[1])[0];

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

Как альтернатива , если Вы готовы протестировать происходящий работой Linq на NHibernate в nhcontrib, Вы могли бы найти, что можно сделать что-то вроде этого:

var itemSpec = (from i in Item where i.Age > age);
var count = itemSpec.Count();
var list = itemSpec.Skip(10).Take(10).AsList(); 

, Очевидно, нет никакого продолжения пакетной обработки, таким образом, это не так эффективно, но это может все еще комплект Ваши потребности?

Hope это помогает!

3
ответ дан tobinharris 3 October 2008 в 17:50
поделиться

Я знаю эту проблему и столкнулся с нею прежде. Для начала, двойной механизм запроса, где это делает те же ИЗБРАННЫЕ условия, действительно не оптимален. Но, это работает, и прежде чем Вы уйдете и сделаете некоторое гигантское изменение, просто поймете, что это не могло бы стоить того.

, Но, так или иначе:

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

2) Модернизация запрос так, чтобы Вы получили КОЛИЧЕСТВО (*) как дополнительный столбец в нормальных строках. Да, это содержит то же значение для каждой строки, но это только включает 1 дополнительный столбец, который является целым числом. Это - неподходящий SQL для представления агрегированного значения с не агрегированные значения, но он может работать.

3) Модернизация запрос для использования предполагаемого предела, подобного тому, что упоминалось. Используйте строки на страницу и некоторый верхний предел. Например, просто скажите что-то как "Показ 1 - 10 из 500 или больше". Когда они просматривают к "Показу 25o к 260 из X", это - более поздний запрос, таким образом, можно просто обновить эти X оценок путем создания верхней границы относительно страницы * строки/страница.

2
ответ дан Josh 3 October 2008 в 17:50
поделиться

Я думаю, что решение зависит от базы данных, которую вы используете. Например, мы используем MS SQL и используем следующий запрос

select 
  COUNT(Table.Column) OVER() as TotalRowsCount,
  Table.Column,
  Table.Column2
from Table ...

. Эта часть запроса может быть изменена с помощью указанного в базе данных SQL.

Также мы устанавливаем максимальный результат запроса, который ожидаем увидеть, например,

query.setMaxResults(pageNumber * itemsPerPage)

И получаем Экземпляр ScrollableResults как результат выполнения запроса:

ScrollableResults result = null;
try {
    result = query.scroll();
    int totalRowsNumber = result.getInteger(0);
    int from = // calculate the index of row to get for the expected page if any

    /*
     * Reading data form page and using Transformers.ALIAS_TO_ENTITY_MAP
     * to make life easier.
     */ 
}
finally {
    if (result != null) 
        result.close()
}
1
ответ дан 27 November 2019 в 05:03
поделиться

На этой вики-странице Hibernate:

https://www.hibernate.org/314.html

Я представляю полное решение для нумерации страниц; в частности, общее количество элементов вычисляется путем прокрутки до конца набора результатов, который теперь поддерживается несколькими драйверами JDBC. Это позволяет избежать второго запроса «count».

1
ответ дан 27 November 2019 в 05:03
поделиться
Другие вопросы по тегам:

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