JDBC — групповые операции

Много запросов с помощью Batch-метода

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

В принципе вот и все — ничего сверхсложного там нет. Могу только посоветовать не увлекаться и не вставлять больше нескольких сотен запросов за раз и обратить внимание, что executeBatch возвращает массив целых чисел (попробуйте сами догадаться, что он значит — в качестве подсказки посмотрите, что возвращает executeUpdate).
Также есть смысл посмотреть на работу getGeneratedKeys() — если вы уже забыли, что это такое — посмотрите предыдущую статью.

Много запросов в одном Statement

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

Как видите, мы в одну строку поместили ДВА SQL-запроса — один SELECT и один DELETE. После этого мы выполняем метод execute(), который возвращает true, если первое возвращаемое значение является ResultSet или false — если это был запрос на модификацию.
Для перехода к результату исполнения следующего запроса вызывается метод getMoreResults()он также возвращает true в случае, если следующий результат является типом ResultSet или false — это значит, что либо SQL-запрос выполнял модификацию, либо больше результатов нет. Чтобы выбрать между этими двумя вариантами надо обратиться к методу getUpdateCount. Если возвращается 0 и больше — значит выполнялся запрос на модификацию. Если результат равен -1 — значит больше запросов нет.

И наконец, полный текст примера для обоих случаев — покопайтесь в нем самостоятельно. Обратите внмание на более лаконичную конструкцию для try с ресурсами. Она появилась в java 1.7 = думаю, самое время вам понять, что и как там происходит. (в общем ничего сложного — ресурс автоматически закрывается)

Сам проект можно скачать здесь — BatchExampleDb.zip

Что осталось за кадром

Сейчас не могу сказать, будет ли этот раздел по базам данных в Java заключительным, но пока планирую именно так — впереди только наш замечательный пример с контактами. Какие возможности и особенности есть у JDBC еще, вы можете посмотреть сами. Мы еще много чего не разбирали:

  • работа с BLOB (binary large object)
  • вызов процедур через интерфейс CallableStatement
  • модификация ResultSet
  • использование RowSet с его расширениями.
  • создание и использование собственных типов данных
  • работа с массивами
  • работа с XML

В общем, я оставляю на вашу собственную голову достаточно широкий спектр вопросов. Весьма неплохое руководство можно посмотреть на сайте Oracle здесь: Trail: JDBC(TM) Database Access.

И теперь нас ждет следующая статья: Список контактов — работаем с БД

4 comments to JDBC — групповые операции

  • Shmel  says:

    При выполнении последней программы «BatchExampleDb» такая вот ошибка:

    com.microsoft.sqlserver.jdbc.SQLServerException: Перед получением результатов необходимо выполнить инструкцию.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:227)
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.getGeneratedKeys(SQLServerStatement.java:2108)
    at DB.BatchExampleDb.addBatch(BatchExampleDb.java:42)
    at DB.BatchExampleDb.main(BatchExampleDb.java:17)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

    Я использую MS SQL Server

    • admin  says:

      Вполне может быть такая ошибка — там при вставке генерируется автоматически идентификатор и это делается средствами именно PostgreSQL.
      Для MS SQL идентификатор может генерироваться иначе. Вот и ошибка.

  • Александр  says:

    Благодарю Вас за статью, очень полезная и лаконичная информация о том, что волнует.

    Написано просто замечательно.

    Вот только не хватает раздела о работе с XML.

    Может, Вы могли бы добавить немножко об этом? Цены Вашим материалам не будет.

    • admin  says:

      Как я понял, речь идет о работе с XML именно для баз данных ? Надо подумать. На самом деле там много чего еще есть — надо как-то соблюсти баланс между простотой изложения и глубиной погружения.

Leave a reply Cancel reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.