Spec-Zone .ru
спецификации, руководства, описания, API
След: JDBC (ТМ) Доступ к базе данных
Урок: Основы JDBC
Используя CachedRowSetObjects
Домашняя страница > JDBC (ТМ) Доступ к базе данных > Основы JDBC

Используя CachedRowSetObjects

A CachedRowSet объект является особенным в этом, он может работать, не будучи соединенным с его источником данных, то есть, это - разъединенный RowSet объект. Это получает свое имя от факта, что это хранит (кэши) свои данные в памяти так, чтобы это могло работать на ее собственных данных, а не на данных, хранивших в базе данных.

CachedRowSet интерфейс является суперинтерфейсом для всех разъединенных RowSet объекты, таким образом, все демонстрировало здесь также, применяются к WebRowSet, JoinRowSet, и FilteredRowSet объекты.

Отметьте что хотя источник данных для a CachedRowSet объект (и RowSet объекты, полученные из этого), почти всегда реляционная база данных, a CachedRowSet объект способен к получению данных от любого источника данных, который хранит его данные в табличном формате. Например, плоский файл или электронная таблица могли быть источником данных. Это - истина когда RowSetReader объект для разъединенного RowSet объект реализуется, чтобы считать данные из такого источника данных. Ссылочная реализация CachedRowSet у интерфейса есть a RowSetReader возразите, что данные чтений от реляционной базы данных, таким образом, в этом учебном руководстве, источник данных всегда является базой данных.

Следующие темы затрагиваются:

Установка Объектов CachedRowSet

Установка a CachedRowSet объект включает следующее:

Создание Объектов CachedRowSet

Можно создать новое CachedRowSet объект различными способами:

Отметьте: Альтернативно, можно использовать конструктора от CachedRowSet реализация Вашего драйвера JDBC. Однако, реализации RowSet интерфейс будет отличаться от ссылочной реализации. У этих реализаций будут различные имена и конструкторы. Например, Oracle реализация драйвера JDBC CachedRowSet интерфейс называют oracle.jdbc.rowset.OracleCachedRowSet.

Используя Конструктора по умолчанию

Один из путей можно создать a CachedRowSet объект, вызывая конструктора по умолчанию, определенного в ссылочной реализации, как делается в следующей строке кода:

CachedRowSet crs = new CachedRowSetImpl();

Объект crs имеет те же самые значения по умолчанию для его свойств это a JdbcRowSet объект имеет, когда он сначала создается. Кроме того, это было присвоено экземпляр значения по умолчанию SyncProvider реализация, RIOptimisticProvider.

A SyncProvider возразите предоставляет a RowSetReader объект (читатель) и a RowSetWriter объект (писатель), который разъединенный RowSet возразите потребностям, чтобы считать данные из его источника данных или записывать данные обратно к его источнику данных. Какой читатель и писатель делают объясняется позже в разделах, Что Делает Читатель и Что Делает Писатель. Одна вещь иметь в виду состоит в том, что читатели и писатели работают полностью в фоновом режиме, таким образом, объяснение того, как они работают, для Вашей информации только. Наличие некоторого фона на читателях и писателях должно помочь Вам понять что некоторые из методов, определенных в CachedRowSet интерфейс делает в фоновом режиме.

Установка Свойств CachedRowSet

Обычно, значения по умолчанию для свойств прекрасны, как они, но можно изменить значение свойства, вызывая соответствующий метод метода set. Есть некоторые свойства без значений по умолчанию, которые следует установить самостоятельно.

Чтобы получить данные, разъединенный RowSet объект должен быть в состоянии соединиться с источником данных и иметь некоторые средства выбора данных, которые это должно содержать. Следующие свойства содержат информацию, необходимую, чтобы получить соединение с базой данных.

То, который из этих свойств следует установить, зависит от того, как Вы собираетесь сделать соединение. Привилегированный путь состоит в том, чтобы использовать a DataSource объект, но это, возможно, не практично для Вас, чтобы зарегистрировать a DataSource объект с JNDI именование службы, которая обычно делается системным администратором. Поэтому, примеры кода все использование DriverManager механизм, чтобы получить соединение, для которого Вы используете url свойство а не datasourceName свойство.

Следующие строки кодового набора username, password, и url свойства так, чтобы соединение могло быть получено, используя DriverManager class. (Вы найдете, что URL JDBC устанавливает как значение для url свойство в документации для Вашего драйвера JDBC.)

public void setConnectionProperties(
    String username, String password) {
    crs.setUsername(username);
    crs.setPassword(password);
    crs.setUrl("jdbc:mySubprotocol:mySubname");
    // ...

Другое свойство, которое следует установить, command свойство. В ссылочной реализации данные читаются в a RowSet объект от a ResultSet объект. Запрос, который производит это ResultSet объект является значением для command свойство. Например, следующая строка кодовых наборов command свойство с запросом, который производит a ResultSet объект, содержащий все данные в таблице MERCH_INVENTORY:

crs.setCommand("select * from MERCH_INVENTORY");

Установка Ключевых Столбцов

Если Вы идете, делают любые обновления к crs возразите и хотите те обновления, сохраненные в базе данных, следует установить еще одну информацию: ключевые столбцы. Ключевые столбцы являются по существу тем же самым как первичным ключом, потому что они указывают на один или более столбцов, которые однозначно определяют строку. Различие - то, что первичный ключ устанавливается на таблице в базе данных, тогда как ключевые столбцы устанавливаются на детали RowSet объект. Следующие строки кодового набора ключевые столбцы для crs к первому столбцу:

int [] keys = {1};
crs.setKeyColumns(keys);

Первый столбец в таблице MERCH_INVENTORY ITEM_ID. Это может служить ключевым столбцом, потому что каждый идентификатор элемента отличается и поэтому однозначно определяет одну строку и только одну строку в таблице MERCH_INVENTORY. Кроме того, этот столбец определяется как первичный ключ в определении MERCH_INVENTORY таблица. Метод setKeyColumns берет массив, чтобы учесть факт, что может потребоваться два или больше столбца, чтобы идентифицировать строку уникально.

Как интересное место, метод setKeyColumns не устанавливает значение для свойства. В этом случае это устанавливает значение для поля keyCols. Ключевые столбцы используются внутренне, таким образом, после установки их, Вы не делаете ничего больше с ними. Вы будете видеть, как и когда ключевые столбцы будут использоваться в разделе Используя Объекты SyncResolver.

Заполнение Объектов CachedRowSet

Заполнение разъединенного RowSet объект включает больше работы чем заполнение соединенного RowSet объект. К счастью, дополнительная работа делается в фоновом режиме. После того, как Вы сделали предварительную работу, чтобы установить CachedRowSet объект crs, следующая строка кода заполняет crs:

crs.execute();

Данные в crs данные в ResultSet объект, произведенный, выполняя запрос в свойстве команды.

То, что отличается, то, что CachedRowSet реализация для execute метод делает намного больше чем JdbcRowSet реализация. Или более правильно, CachedRowSet читатель объекта, в котором метод выполняют делегатов его задачи, делает намного больше.

Каждый разъединенный RowSet у объекта есть a SyncProvider объект, присвоенный этому, и это SyncProvider объект состоит в том тем, что обеспечивает RowSet читатель объекта (a RowSetReader объект). Когда crs объект создавался, он использовался в качестве значения по умолчанию CachedRowSetImpl конструктор, который, в дополнение к установке значений по умолчанию для свойств, присваивает экземпляр RIOptimisticProvider реализация как значение по умолчанию SyncProvider объект.

Что Делает Читатель

Когда приложение вызывает метод execute, разъединенный RowSet читатель объекта работает негласно, чтобы заполнить RowSet объект с данными. Недавно создаваемый CachedRowSet объект не соединяется с источником данных и поэтому должен получить соединение с тем источником данных, чтобы получить данные от этого. Ссылочная реализация значения по умолчанию SyncProvider объект (RIOptimisticProvider) предоставляет читателю, который получает соединение при использовании набора значений для имени пользователя, пароля, и или URL JDBC или имя источника данных, какой бы ни был установлен позже. Затем читатель выполняет набор запроса для команды. Это читает данные в ResultSet объект, произведенный запросом, заполняя CachedRowSet объект с теми данными. Наконец, читатель закрывает соединение.

Обновление Объекта CachedRowSet

В сценарии Перерыва на кофе владелец хочет оптимизировать операции. Владелец решает иметь сотрудников в складе, вводят материально-технические ресурсы непосредственно в PDA (персональный цифровой секретарь), таким образом избегая, чтобы подверженный ошибкам процесс наличия второго человека сделал ввод данных. A CachedRowSet объект идеален в этой ситуации, потому что это легко, сериализуемо, и может быть обновлено без соединения с источником данных.

Владелец сделает разработку приложений объединять в команду, создают инструмент GUI для PDA, который складские сотрудники будут использовать для того, чтобы ввести данные учета. Штаб создаст a CachedRowSet объект, заполненный с таблицей, показывая текущие материально-технические ресурсы и, отправляет это использующий Интернет для PDA. Когда складской сотрудник вводит данные, используя инструмент GUI, инструмент добавляет каждую запись в массив, который CachedRowSet объект будет использовать, чтобы выполнить обновления в фоновом режиме. После завершения материально-технических ресурсов PDA отсылают свои новые данные назад к штабу, где данные загружаются на основной сервер.

Этот раздел затрагивает следующие темы:

Обновление Значений столбцов

Обновление данных в a CachedRowSet объект все равно как обновляет данные в a JdbcRowSet объект. Например, следующий фрагмент кода от CachedRowSetSample.java постепенно увеличивает значение в столбце QUAN 1 в строке, чей ITEM_ID у столбца есть идентификатор элемента 12345:

while (crs.next()) {
    System.out.println(
        "Found item " + crs.getInt("ITEM_ID") +
        ": " + crs.getString("ITEM_NAME"));
    if (crs.getInt("ITEM_ID") == 1235) {
        int currentQuantity = crs.getInt("QUAN") + 1;
        System.out.println("Updating quantity to " +
          currentQuantity);
        crs.updateInt("QUAN", currentQuantity + 1);
        crs.updateRow();
        // Synchronizing the row
        // back to the DB
        crs.acceptChanges(con);
    }

Вставка и Удаление Строк

Так же, как с обновлением значения столбца, кода для вставки и удаления строк в a CachedRowSet объект является тем же самым что касается a JdbcRowSet объект.

Следующая выборка от CachedRowSetSample.java вставляет новую строку в CachedRowSet объект crs:

crs.moveToInsertRow();
crs.updateInt("ITEM_ID", newItemId);
crs.updateString("ITEM_NAME", "TableCloth");
crs.updateInt("SUP_ID", 927);
crs.updateInt("QUAN", 14);
Calendar timeStamp;
timeStamp = new GregorianCalendar();
timeStamp.set(2006, 4, 1);
crs.updateTimestamp(
    "DATE_VAL",
    new Timestamp(timeStamp.getTimeInMillis()));
crs.insertRow();
crs.moveToCurrentRow();

Если бы штаб решил прекратить снабжать определенный элемент, он, вероятно, удалил бы строку для того кофе непосредственно. Однако, в сценарии, у складского сотрудника, использующего PDA также, есть возможность удаления этого. Следующий фрагмент кода находит строку где значение в ITEM_ID столбец 12345 и удаляет это из CachedRowSet crs:

while (crs.next()) {
    if (crs.getInt("ITEM_ID") == 12345) {
        crs.deleteRow();
        break;
    }
}

Обновление Источников данных

Есть существенное различие между произведением изменений в a JdbcRowSet объект и производящие изменения в a CachedRowSet объект. Поскольку a JdbcRowSet объект соединяется с его источником данных, методами updateRow, insertRow, и deleteRow может обновить обоих JdbcRowSet возразите и источник данных. В случае разъединенного RowSet объект, однако, эти методы обновляют данные, хранившие в CachedRowSet память объекта, но не может влиять на источник данных. Разъединенный RowSet объект должен вызвать метод acceptChanges чтобы сохранить его изменения к источнику данных. В сценарии материально-технических ресурсов, назад в штабе, приложение вызовет метод acceptChanges обновить базу данных с новыми значениями для столбца QUAN.

crs.acceptChanges();

Что Делает Писатель

Как метод execute, метод acceptChanges делает его работу незримо. Принимая во внимание, что метод execute делегирует его работу к RowSet читатель объекта, метод acceptChanges делегирует его задачи к RowSet писатель объекта. В фоновом режиме писатель открывает соединение с базой данных, обновляет базу данных с изменениями, произведенными в RowSet объект, и затем закрывает соединение.

Используя Реализацию по умолчанию

Трудность состоит в том, что конфликт может возникнуть. Конфликт является ситуацией, в которой другая сторона обновила значение в базе данных, которая соответствует значению, которое было обновлено в a RowSet объект. Какое значение должно сохраниться в базе данных? То, что делает писатель, когда есть конфликт, зависит от того, как он реализуется, и есть много возможностей. В одном конце спектра писатель даже не проверяет на конфликты и только пишет все изменения в базу данных. Дело обстоит так с RIXMLProvider реализация, которая используется a WebRowSet объект. С другой стороны, писатель гарантирует, что нет никаких конфликтов, устанавливая блокировки базы данных, которые препятствуют тому, чтобы другие произвели изменения.

Писатель для crs объект является тем, обеспеченным значением по умолчанию SyncProvider реализация, RIOptimisticProvider. RIOPtimisticProvider реализация получает свое имя от факта, что она использует модель оптимистичного параллелизма. Эта модель предполагает, что будут немногие, если таковые вообще имеются, конфликты и поэтому не устанавливают блокировок базы данных. Проверки писателя, чтобы видеть, есть ли какие-либо конфликты, и если нет ни одного, это пишет изменения, произведенные в crs возразите против базы данных, и те изменения становятся персистентными. Если есть какие-либо конфликты, значение по умолчанию не должно записать новое RowSet значения к базе данных.

В сценарии поведение значения по умолчанию работает очень хорошо. Поскольку никто в штабе, вероятно, не изменит значение в QUAN столбец COF_INVENTORY, не будет никаких конфликтов. В результате значения, в которые вводят crs объект в складе будет записан базе данных и таким образом будет персистентным, который является желаемым результатом.

Используя Объекты SyncResolver

В других ситуациях, однако, для конфликтов возможно существовать. Размещать эти ситуации, RIOPtimisticProvider реализация предоставляет возможность, которая позволяет Вам смотреть на значения в конфликте и решать, которые должны быть персистентными. Эта опция является использованием a SyncResolver объект.

Когда писатель закончил искать конфликты и нашел один или больше, это создает a SyncResolver объект, содержащий значения базы данных, которые вызвали конфликты. Затем, метод acceptChanges броски a SyncProviderException объект, который приложение может поймать и использовать, чтобы получить SyncResolver объект. Следующие строки кода получают SyncResolver объект resolver:

try {
    crs.acceptChanges();
} catch (SyncProviderException spe) {
    SyncResolver resolver = spe.getSyncResolver();
}

Объект resolver a RowSet объект, который тиражируется crs возразите за исключением того, что это содержит только значения в базе данных, которая вызвала конфликт. Все другие значения столбцов являются нулем.

С resolver объект, можно выполнить итерации через его строки, чтобы определить местоположение значений, которые не являются нулем и являются поэтому значениями, которые вызвали конфликт. Затем можно определить местоположение значения в той же самой позиции в crs возразите и сравните их. Следующий фрагмент кода получает resolver и использование SyncResolver метод nextConflict выполнить итерации через строки, у которых есть конфликтные значения. Объект resolver получает состояние каждого конфликтного значения, и если это UPDATE_ROW_CONFLICT, подразумевать, что crs делал попытку обновления, когда конфликт произошел, resolver объект получает номер строки того значения. Затем код перемещает курсор для crs возразите против той же самой строки. Затем, код находит столбец в той строке resolver объект, который содержит конфликтное значение, которое будет значением, которое не является нулем. После получения значения в том столбце от обоих resolver и crs объекты, можно сравнить два и решить, какой Вы хотите стать персистентными. Наконец, кодовые наборы, которые оценивают в обоих crs возразите и база данных, используя метод setResolvedValue, как показано в следующем коде:

try {
    crs.acceptChanges();
} catch (SyncProviderException spe) {
    SyncResolver resolver = spe.getSyncResolver();
  
    // value in crs
    Object crsValue;
  
    // value in the SyncResolver object
    Object resolverValue; 
  
    // value to be persistent
    Object resolvedValue; 

    while (resolver.nextConflict()) {
        if (resolver.getStatus() ==
            SyncResolver.UPDATE_ROW_CONFLICT) {
            int row = resolver.getRow();
            crs.absolute(row);
            int colCount =
                crs.getMetaData().getColumnCount();
            for (int j = 1; j <= colCount; j++) {
                if (resolver.getConflictValue(j)
                    != null) {
                    crsValue = crs.getObject(j);
                    resolverValue = 
                        resolver.getConflictValue(j);

                    // ...
                    // compare crsValue and
                    // resolverValue to
                    // determine the value to be
                    // persistent

                    resolvedValue = crsValue;
                    resolver.setResolvedValue(
                        j, resolvedValue);
                }
            }
        }
    }
}

Уведомление Слушателей

Быть компонентом JavaBeans означает это a RowSet объект может уведомить другие компоненты, когда определенные вещи происходят с ним. Например, если данные в a RowSet возразите изменениям, RowSet объект может уведомить заинтересованные стороны того изменения. Хорошая вещь об этом механизме уведомления состоит в том, что, как прикладной программист, все, что необходимо сделать, добавляют или удаляют компоненты, которые будут уведомлены.

Этот раздел затрагивает следующие темы:

Установка Слушателей

Слушатель для a RowSet объект является компонентом, который реализует следующие методы от RowSetListener интерфейс:

Примером компонента, который мог бы хотеть быть слушателем, является a BarGraph возразите что графики данные в a RowSet объект. Поскольку данные изменяются, BarGraph объект может обновить себя, чтобы отразить новые данные.

Как прикладной программист, единственная вещь следует сделать, чтобы использовать в своих интересах механизм уведомления, должен добавить или удалить слушателей. Следующая строка кода означает что каждый раз курсор для crs перемещения объектов, значения в crs изменяются, или crs в целом получает новые данные, BarGraph объект bar будет уведомлен:

crs.addRowSetListener(bar);

Можно также остановить уведомления, удаляя слушателя, как делается в следующей строке кода:

crs.removeRowSetListener(bar);

Используя сценарий Перерыва на кофе, предположите, что штаб сверяется с базой данных периодически, чтобы получить последний прейскурант для кофе, которые это продает онлайн. В этом случае слушатель PriceList объект priceList на веб-сайте Перерыва на кофе, который должен реализовать RowSetListener методы cursorMoved, rowChanged, и rowSetChanged. Реализация cursorMoved метод мог быть должен ничего не сделать, потому что позиция курсора не влияет priceList объект. Реализации для rowChanged и rowSetChanged методы, с другой стороны, должны установить то, что изменения были произведены и обновление priceList соответственно.

Как Уведомление Работает

В ссылочной реализации, методы, которые вызывают любой из RowSet события автоматически уведомляют всех зарегистрированных слушателей. Например, любой метод, который перемещает курсор также, вызывает метод cursorMoved на каждом из слушателей. Точно так же метод execute вызывает метод rowSetChanged на всех слушателях, и acceptChanges вызовы rowChanged на всех слушателях.

Отправка Больших Объемов данных

Пример кода CachedRowSetSample.testCachedRowSet демонстрирует, как данные могут быть отправлены в мелких кусочках.


Проблемы с примерами? Попытайтесь Компилировать и Выполнить Примеры: FAQ.
Жалобы? Поздравление? Предложения? Дайте нам свою обратную связь.

Предыдущая страница: Используя Объекты JdbcRowSet
Следующая страница: Используя Объекты JoinRowSet