что такое resultset как с ним работать
Результаты запроса ResultSet
Класс ResultSet представляет результирующий набор данных и обеспечивает приложению построчный доступ к результатам запросов. При обработке запроса ResultSet поддерживает указатель на текущую обрабатываемую строку.
Доступ к данным ResultSet обеспечивает посредством набора get-методов, которые организуют доступ к колонкам текущей строки. Метод ResultSet.next используется для перемещения к следующей строке ResultSet, делая ее текущей.
Методы ResultSet
Список наиболее часто используемых методов класса ResultSet представлен в таблице :
Пример использования ResultSet
Результирующий набор данных ResultSet можно не закрывать. Это делается автоматически родительским объектом Statement, когда он закрывается, начинает выполняться повторно или используется для извлечения следующего результата в последовательности нескольких результатов. Но лучше все же закрывать и не надеяться, что это сделает разработчик драйвера JDBC.
Значение NULL в ResultSet
Чтобы определить, равно ли значение определенной колонки NULL или нет, необходимо сначала прочитать значение колонки, а затем использовать метод wasNull класса ResultSet для выяснения данного факта. Если wasNull возвращает значение true, то это означает, что считанное значение равно NULL.
В случае, если возвращаемое значение NULL, то методы ResultSet.getXXX, равны:
Строки, колонки и курсоры ResultSet
ResultSet содержит так называемый курсор, который позиционируется на текущей строке данных. При вызове метода next, курсор перемещается на следующую строку.
При открытии набора данных ResultSet курсор расположен перед первой строкой, и первый вызов next передвигает его на первую строку.
ResultSet хранит курсор до самого закрытия или пока не закроется родительский объект Statement.
Курсор для результирующей таблицы имеет имя. Если БД поддерживает позиционированные обновления или позиционированные удаления, то командам обновления или удаления можно передать в качестве параметра имя курсора, которое можно получить с помощью вызова метода getCursorName()
Но не все СУБД могут поддерживать позиционированные обновления или удаления. Чтобы узнать, поддерживает ли данное соединение Connection эти операции или нет, можно вызвать методы DatabaseMetaData.supportsPositionedDelete и supportsPositionedUpdate.
Методы ResultSet.getXXX предоставляют доступ к значениям в колонках в текущей строке. В пределах одной строки значения могут быть считаны в любом порядке. Для обеспечения бо́льшей совместимости рекомендуется считывать их подряд слева направо и делать это только один раз. Для указания колонки можно использовать либо ее имя, либо ее номер. Например, если вторая колонка объекта ResultSet rs называется «title» и хранит строковое значение, то извлечь его можно одним из двух способов:
При обращении к колонке по номеру следует помнить, что колонки нумеруются слева направо, начиная с 1, а имена колонок в вызове методов getXXX нечувствительны к регистру букв.
Наименования колонок совпадает с соответствующими наименованиями колонок в запросе. Если же в выражении select не указываются имена колонок (например «select * from users»), то необходимо либо использовать номера колонок, либо «подключать» метаданные. Информацию о колонках в ResultSet можно получить с помощью вызова ResultSet.getMetaData. Возвращаемый объект ResultSetMetaData содержит информацию о количестве, типах и свойствах колонок объекта ResultSet.
В некоторых случаях имена двух колонок могут совпадать. Тогда при использовании имен колонок в методах getXXX возвращается значение первой подходящей колонки. Таким образом, чтобы считать значение других колонок с таким же именем, надо использовать индексы колонок. Кроме того, использование индексов немного эффективнее.
Если имя колонки известно, а индекс нет, то для поиска номера колонки можно использовать метод findColumn().
Типы данных и их преобразование
Различные методы чтения записей типа getXXX конвертируют низкоуровневые данные в типы данных Java. Например, если в таблице БД тип данных VARCHAR, то при использовании метода getString, драйвер JDBC конвертирует VARCHAR в объект String. Т.е. возвращаемым из метода getString значением будет объект String.
Следующая таблица показывает, какие типы данных различные методы getXXX могут считывать и какие JDBC-типы (SQL-типы) рекомендуются для этих методов.
Например, для типа данных LONGVARCHAR значение можно извлечь любым из методов getXXX кроме getBytes и getBinaryStream, но рекомендуется использовать методы getAsciiStream и getUnicodeStream.
Метод getObject возвращает значение как Object и может быть использован в тех случаях, когда соответствующий низкоуровневый тип данных является специфичным для данной СУБД, или когда приложению необходимо принять любой тип данных.
Таблица соответствия методов ResultSet.getXXX при чтении значений различных типам данных SQL.
T I N Y I N T | S M A L L I N T | I N T E G E R | B I G I N T | R E A L | F L O A T | D O U B L E | D E C I M A L | N U M E R I C | B I T | C H A R | V A R C H A R | L O N G V A R C H A R | B I N A R Y | V A R B I N A R Y | L O N G V A R B I N A R Y | D A T E | T I M E | T I M E S T A M P | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
getByte | X | x | x | x | x | x | x | x | x | x | x | x | x | ||||||
getShort | x | X | x | x | x | x | x | x | x | x | x | x | x | ||||||
getInt | x | x | X | x | x | x | x | x | x | x | x | x | x | ||||||
getLong | x | x | x | X | x | x | x | x | x | x | x | x | x | ||||||
getFloat | x | x | x | x | X | x | x | x | x | x | x | x | x | ||||||
getDouble | x | x | x | x | x | X | X | x | x | x | x | x | x | ||||||
getBigDecimal | x | x | x | x | x | x | x | X | X | x | x | x | x | ||||||
getBoolean | x | x | x | x | x | x | x | x | x | X | x | x | x | ||||||
getString | x | x | x | x | x | x | x | x | x | x | X | X | x | x | x | x | x | x | x |
getBytes | X | X | x | ||||||||||||||||
getDate | x | x | x | X | x | ||||||||||||||
getTime | x | x | x | X | x | ||||||||||||||
getTimestamp | x | x | x | x | X | ||||||||||||||
getAsciiStream | x | x | X | x | x | x | |||||||||||||
getUnicodeStream | x | x | X | x | x | x | |||||||||||||
getBinaryStream | x | x | X | ||||||||||||||||
getObject | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
Чтение больших LOB объектов
Для чтения больших объектов LOB (Large Object Bynary) также используется ResultSet. Методы getBytes и getString возвращают эти данные в виде одного большого массива (байт, символов). Можно узнать размер объекта с помощью метода Statement.getMaxFieldSize.
Можно большие объекты LOB читать с помощью потоков (java.io.InputStream), которые возвращаются некоторыми методами ResultSet. Следует обратить внимание на то, что к этим потокам надо обращаться сразу, так как они будут закрыты при следующем вызове getXXX объекта ResultSet. Такое поведение диктуется низкоуровневой реализацией доступа к большим двоичным объектам.
JDBC API включает три отдельных метода для чтения данных в поток :
Эти потоки отличаются от обычных потоков Java, которые возвращают нетипизированные байты.
Следующий пример демонстрирует использование getAsciiStream :
Пример записи файлов в бинарные (BLOB) и символьные (CLOB/TEXT) поля баз данных Oracle и MySQL можно увидеть здесь.
Множественные наборы : getResultSet, getUpdateCount, getMoreResults
Обычно при выполнении SQL-запросов используют либо метод executeQuery, возвращающий единственный ResultSet, либо executeUpdate, который может быть использован для изменения значения в таблице БД и который возвращают количество измененных строк. Тем не менее, в отдельных случаях приложению заранее может быть неизвестно, возвратит ли данный запрос результат или нет. Кроме этого, некоторые хранимые процедры могут возвратить несколько наборов данных и/или счетчиков обновления.
Для этого случая в JDBC есть механизм, когда приложение может обрабатывать произвольную коллекцию наборов результатов или счетчиков обновления. Данный механизм основан на вызове метода execute и последующем вызове трех других методов getResultSet, getUpdateCount и getMoreResults.
Методы getResultSet, getUpdateCount и getMoreResults позволяют приложению получать результаты запроса по-очереди и для каждого результата определять, является ли он набором данных или счетчиком обновлений.
Непопулярное в JDBC
О API JDBC достаточно много информации и гайдов, но к сожалению почти все как под копирку. Сам достаточно долгое время осваивал это чудо, переводя ресурсы умных.
Привет, Хабр!
Не так давно узнал о некоторых приемах создания соединения и дальнейшей работы с ним.
На 100% уникальность не претендую, лавры не собираю.
В общем, типичная задача, подключится к БД и запросить данные из таблицы. Что мы делаем для этого:
Прокручиваемый ResultSet
Начиная с версии JDBC 2.0 появилась возможность направленной прокрутки набора результата.
Для этого, при создании Statement необходимо указать параметр желаемой прокрутки.
Редактируемый ResultSet
Возможно, в коде выше вы заметили второй параметр — ResultSet.CONCUR_READ_ONLY, он означает, что выбранный результат доступен только для чтения.
Вместо создания привычных стейтментов для обновления (вставка, редактирование, удаление) мы можем воспользоваться ранее созданным ResultSet`ом. Но для этого во второй параметр метода по созданию Statement необходимо указать ResultSet.CONCUR_UPDATABLE.
В таком ResultSet вы сможете не только обновлять выбранные записи, но и создавать новые, а также производить удаление.
Пакетные обновления
Для большей скорости, операций по обновлению данных БД рекомендуется делать в пакетах.
Т.е. это когда вы например добавляете строки в таблицу и не отправляете их каждую по отдельности на сервер, а делаете это в конце.
Сразу скажу, что в этих случаях необходимо выключит AutoCommit у соединения, т.к. отправлять изменения на сервер мы будем принудительно.
А также, нужно проверить, поддерживает ли версия драйвера пакетные обновления — DatabaseMetaData.supportsBatchUpdates().
Заключение
Данная статья не является гайдом о том как нужно делать. Большинство примеров представлено в тезисном варианте, цель которого — передать коротко и лаконично основную мысль. В следующей статье напишу про RowSet`ы и что нибудь еще, непопулярное!
Руководство по JDBC. Result Set.
В прошлом уроке мы рассмотрели понятие Statements и их виды. Мы узнали, что в результате SQL – запроса мы получаем данные.
Данные, полученные в результате SQL – запроса возвращаются в виде множества результатов, которые хранятся в сущности под названием Result Set.
Стандартный способ получить записи из нашей базе данных (далее – БД) – это применение ключевого слова SELECT. Стандартный способ просмотреть эти данные – это использовать Result set.
Интерфейс java.sql.ResultSet представляет собой множество результатов, запроса в БД.
Экземпляр ResultSet имеет указатель, который указывает на текущую строку в полученном множестве.
Все методы интерфейса java.sql.ResultSet мы можем разделить на три большие группы:
Курсор двигается на основе свойств ResultSet. Эти свойства указываются при создании экземпляра ResultSet.
Для определения этих свойств используются следующие методы:
Аргумент RSType определяет тип ResultSet, а второй – определяет, используется ли данный экземпляр ResultSet только для чтения, или для чтения и изменения также.
Типы ResultSet
Возможные типы ResultSet приведены ниже. Тип TYPE_FORWARD_ONLY используется по умолчанию.
Рассмотрим эти типы:
Доступ ResultSet
По умолчанию RSConcurrency экземпляра ResultSet установлен тип CONCUR_READ_ONLY, т.е. только для чтения.
Всего существует два типа этого параметра:
В виде кода, создание экземпляра ResultSet с необходимыми нам параметрами выглядит, примерно так:
Навигация по ResultSet
В интерфейсе java.sql.ResultSet существует несколько методов для перемещения указателя.
Некоторые из них приведены ниже:
Для понимания того, как это работает на практике, рассмотрим пример простого приложения.
В результате работы программы мы получим, следующий результат:
Просмотр результатов ResultSet
Для получения и редактирования данных, в интерфейса ResultSet существует множество методов.
Мы можем получить данные, как по имени, так и индексу:
Существуют также методы для получения определённых типов данных SQL (java.sql.Time, java.sql.Date и т.д.).
Для понимания того, как это работает на практике, рассмотрим следующий пример.
В результате работы программы мы получим следующий результат:
Редактирование данных ResultSet
Для редактирования данных, в интерфейсе java.sql.ResultSet, также разработано множество методов.
Мы можем изменять данные, как по имени, так и по индексу колонки:
Мы также можем работать с рядами в таблице БД:
Для понимания того, как это работает на практике, рассмотрим такой пример.
В результате работы программы мы получим следующий результат:
В этом уроке мы изучили такой важный элемент, как ResultSet, его методы, применение и рассмотрели примеры приложений с его использованием.
В следующем уроке мы изучим типы данных JDBC.
Русские Блоги
JDBC (четыре) ResultSet подробно
Тип набора результатов, параллелизм и устойчивость
При создании ResultSet вы можете установить три свойства:
1. Самый простой ResultSet.
Причина, по которой он считается самым простым ResultSet, заключается в том, что функция этого ResultSet заключается в выполнении функции хранения результатов запроса, и он может быть прочитан только один раз и не может быть прокручен назад и вперед. набор результатов выглядит следующим образом:
Поскольку этот набор результатов не поддерживает функцию чтения с прокруткой, если вы получите такой набор результатов, вы можете использовать в нем метод next () только для чтения данных по одному.
2. Прокручиваемый тип ResultSet.
Этот тип поддерживает прокрутку назад и вперед для получения записей next (), previous (), возврат к первой строке first (), а также поддерживает absolute (int n) в первых нескольких строках ResultSet to go и переход к первая строка относительно текущей строки.Несколько строк относительных (int n), чтобы получить такой ResultSet, используйте следующий метод при создании оператора.
Значение двух параметров:
ResultSetConcurency можно изменить, установив объект ResultSet, а значения будут следующими:
ResultSet.CONCUR_READ_ONLY устанавливается как параметр только для чтения.
ResultSet.CONCUR_UPDATABLE устанавливается в параметр изменяемого типа.
Поэтому, если вам нужен только прокручиваемый тип результата, просто назначьте оператор следующим образом.
Оператор запроса, выполняемый с этим оператором, является прокручиваемым набором результатов.
3. Обновляемый ResultSet
Такой объект ResultSet может завершить модификацию таблицы в базе данных, но я знаю, что ResultSet эквивалентен только представлению таблицы в базе данных, поэтому время от времени все ResultSet могут обновляться, если они установлены. до обновления и может завершить обновленный SQL обновленного ResultSet. Оператор должен иметь следующие атрибуты:
a, указывается только одна таблица.
b, не содержит предложений join или group by.
в. Эти столбцы должны содержать первичный ключ.
При выполнении вышеуказанных условий обновляемый ResultSet может завершить модификацию данных. Метод создания обновляемого набора результатов:
Вы также можете использовать метод updateXXX для завершения операции вставки. Но сначала мы должны ввести два метода:
moveToCurrentRow () Перемещение ResultSet в строку в памяти, обычно текущую строку. Если операция вставки не используется, этот метод не имеет никакого эффекта. Если используется операция вставки, этот метод используется для возврата к строке перед операцией вставки, оставьте вставленную строку, конечно, вы также можете оставить вставленную строку с помощью next (), previous () и других методов.
Чтобы завершить вставку в базу данных, сначала вызовите moveToInsertRow (), чтобы перейти к вставленной строке, а затем вызовите метод updateXXX, чтобы завершить обновление. После завершения обновления, как и операция обновления, он должен быть записан в database, но здесь используется insertRow. (), также убедитесь, что ResultSet не покидает вставленный столбец до выполнения метода, иначе вставка не будет выполнена, и обновление вставленной строки будет потеряно.
4. Сохраняемый ResultSet
В обычных обстоятельствах, если вы используете Statement для выполнения запроса и выполнения другого запроса в это время, набор результатов первого запроса будет закрыт, то есть все запросы Statement соответствуют одному набору результатов. Если вы вызываете фиксацию Connection () также закроет набор результатов. Удержание относится к тому, закрывается ли результат ResultSet или нет, когда результат ResultSet отправлен. JDBC2.0 и 1.0 предусматривают, что ResultSet будет закрыт после отправки. Но в JDBC3.0 мы можем установить, закрывается ли ResultSet. Чтобы завершить создание такого объекта ResultSet, создание используемого оператора должно иметь три параметра.Метод создания этого оператора является третьим методом создания оператора, который я вызываю.
При использовании ResultSet, когда в запрашиваемом наборе данных много записей (10 миллионов), будет ли объект, на который указывает rs, занимать много памяти? Если записей слишком много, Будет ли программа использовать память системы?
Нет, ResultSet выглядит как набор записей. Фактически, этот объект записывает только соответствующую информацию набора результатов. Конкретные записи не хранятся в объекте. Конкретное содержание записи Знайте что, когда вы извлекаете содержимое поля с помощью следующего метода, вы можете получить его из базы данных, когда извлекаете содержимое поля с помощью связанного метода getXXXXX. Они не занимают память. Конкретное потребление памяти связано с тем, что вы извлекаете данные в набор записей и добавление его к себе Это происходит только тогда, когда вы находитесь в коллекции.Если вы не используете коллекцию для записи всех записей, не будет потребления памяти.
Перебрать resultSet
Обход ResultSet аналогичен печати и чтению содержимого потока. Он имеет метод next (), который определяет, есть ли данные в объекте. Пример:
Получить данные столбца в таблице данных из ResultSet
Выше есть подробное объяснение, просто упомяните его здесь
Или получите по значению индекса столбца в таблице данных
Но обратите внимание, что тип данных в столбце соответствует типу данных java, чтобы избежать ошибок.
Руководство JDBC TM
5.1 Обзор
5.1.1 Строки и курсоры
5.1.2 Колонки
Для указания колонки можно использовать либо ее имя, либо ее номер. Например, если вторая колонка объекта ResultSet rs называется «title» и хранит строковое значение, то извлечь его можно одним из двух способов:
Имейте ввиду, что колонки нумеруются слева направо, начиная с 1. Имена колонок в вызове методов getXXX нечувствительны к регистру букв.
Вариант с использование имен колонок существует для того, чтобы пользователь задавал методам getXXX те же имена колонок, что он использует в запросе. Если выражение select не указывает имена колонок (например » select * from table1 » или в случаях, когда колонка вычисляется) должны использоваться номера колонок. В этих случаях пользователь не может знать наверняка имена колонок.
В нектороых случаях имена двух колонок могут совпадать. Тогда при использовании имен колонок в методах getXXX возвращается значение первой подходящей колонки. Таким образом, чтобы считать значение других колонок с таким же именем, надо использовать индексы колонок. Кроме того, использование индексов немного эффективнее.
5.1.3 Типы данных и их преобразование
Использование методов ResultSet.getXXX при доступе к различным типам данных SQL.
«x» означает, что метод getXXX может быть использован,
«X» означает, что соответствующий метод рекомендуется использовать для этого типа данных.
T I N Y I N T | S M A L L I N T | I N T E G E R | B I G N | R E A L | F L O A T | D O U B L E | D E C I M A L | N U M E R I C | B I T | C H A R | V A R C H A R | L O N G V A R C H A R | B I N A R Y | V A R B I N A R Y | L O N G V A R B I N A R Y | D A T E | T I M E | T I M E S T A M P | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
getByte | X | x | x | x | x | x | x | x | x | x | x | x | x | ||||||
getShort | x | X | x | x | x | x | x | x | x | x | x | x | x | ||||||
getInt | x | x | X | x | x | x | x | x | x | x | x | x | x | ||||||
getLong | x | x | x | X | x | x | x | x | x | x | x | x | x | ||||||
getFloat | x | x | x | x | X | x | x | x | x | x | x | x | x | ||||||
getDouble | x | x | x | x | x | X | X | x | x | x | x | x | x | ||||||
getBigDecimal | x | x | x | x | x | x | x | X | X | x | x | x | x | ||||||
getBoolean | x | x | x | x | x | x | x | x | x | X | x | x | x | ||||||
getString | x | x | x | x | x | x | x | x | x | x | X | X | x | x | x | x | x | x | x |
getBytes | X | X | x | ||||||||||||||||
getDate | x | x | x | X | x | ||||||||||||||
getTime | x | x | x | X | x | ||||||||||||||
getTimestamp | x | x | x | x | X | ||||||||||||||
getAsciiStream | x | x | X | x | x | x | |||||||||||||
getUnicodeStream | x | x | X | x | x | x | |||||||||||||
getBinaryStream | x | x | X | ||||||||||||||||
getObject | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x |