Есть ли портативный способ иметь семантику «SELECT FIRST 10 * FROM T»? - PullRequest
12 голосов
/ 04 августа 2010

Я хочу прочитать данные в блоках, скажем, по 10 тыс. Записей из базы данных.

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

Другим подходом может быть JdbcTemplate , который предлагает множество методов для запросов, но как я могу решить, что было прочитано достаточно строк. С помощью обратных вызовов, таких как RowMapper и ResultSetExtractor, невозможно указать, что достаточно данных было прочитано.

РЕДАКТИРОВАТЬ: я искал решение для JdbcTemplate В этом посте предлагается использовать setMaxRows , который я пропустил.

Ответы [ 5 ]

14 голосов
/ 04 августа 2010

Grab Hibernate или JPA .Оба знакомы с различными диалектами баз данных и будут прозрачно обрабатывать неприятные особенности БД под капотами.

В Hibernate вы можете разбивать на страницы, используя Criteria#setFirstResult() и Criteria#setMaxResults(),Например,

List users = session.createCriteria(User.class)
    .addOrder(Order.asc("id"))
    .setFirstResult(0) // Index of first row to be retrieved.
    .setMaxResults(10) // Amount of rows to be retrieved.
    .list();

В JPA вы можете сделать то же самое, используя Query#setFirstResult() и Query#setMaxResults().

List users = em.createQuery("SELECT u FROM User u ORDER BY u.id");
    .setFirstResult(0) // Index of first row to be retrieved.
    .setMaxResults(10) // Amount of rows to be retrieved.
    .getResultList();
5 голосов
/ 04 августа 2010

Существует стандартный синтаксис ANSI от SQL: 2008 :

SELECT t.* 
  FROM TABLE t
 FETCH FIRST 10 ROWS ONLY

... но в настоящее время он не поддерживается большинством баз данных.

4 голосов
/ 04 августа 2010

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

Используйте уровень абстракции базы данных или DBAL.

http://en.wikipedia.org/wiki/Database_abstraction_layer

http://jonasbandi.net/wiki/index.php/ORM_Solutions_for_Java

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

Если вам нужен переносимый способ, вам нужно подняться на уровень абстракции, так как нет переносимого способа SQL (не тот, который базы данных фактически реализуют в любом случае) - и использовать сопоставители ORM, например, например, hibernate.

Если вам нужен необработанный JDBC, вам придется писать специфический SQL для каждой конкретной базы данных - что часто бывает так, поскольку написание 100% переносимого SQL довольно сложно во всех случаях, кроме тривиальных.

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

1 голос
/ 04 августа 2010

Нет.Вот почему слои абстракции базы данных, такие как Hibernate, содержат диалекты SQL , где вы выбираете тот, который будет использоваться с вашей базой данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...