След: JDBC (ТМ) Доступ к базе данных
Урок: Основы JDBC
Используя Объекты FilteredRowSet
Домашняя страница > JDBC (ТМ) Доступ к базе данных > Основы JDBC

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

A FilteredRowSet объект позволяет Вам сокращать число строк, которые видимы в a RowSet возразите так, чтобы можно было работать с только данными, которые относятся для того, что Вы делаете. Вы решаете то, что ограничивает Вас, хотят установить на Ваших данных (как Вы хотите "фильтровать" данные), и примените тот фильтр к a FilteredRowSet объект. Другими словами, FilteredRowSet объект делает видимым только строки данных, которые соответствуют в пределах пределов, которые Вы устанавливаете. A JdbcRowSet объект, у которого всегда есть соединение с его источником данных, может сделать эту фильтрацию с запросом к источнику данных, который выбирает только столбцы и строки, которые Вы хотите видеть. Запрос WHERE пункт определяет критерии фильтрации. A FilteredRowSet объект обеспечивает путь к разъединенному RowSet объект сделать эту фильтрацию, не имея необходимость выполнять запрос на источнике данных, таким образом избегая имеющий необходимость получить соединение с источником данных и отправляющий запросы этому.

Например, предположите, что цепочка Перерыва на кофе кофеен выросла к сотням хранилищ всюду по Соединенным Штатам Америки, и все они перечисляются в вызванной таблице COFFEE_HOUSES. Владелец хочет измерить успех только хранилищ в Калифорнии с приложением сравнения кофейни, которое не требует персистентного соединения с системой баз данных. Это сравнение будет смотреть на доходность продажи товаров против продажи напитков кофе плюс различные другие меры успеха, и это оценит Калифорнийские хранилища продажами напитка кофе, продажами товаров, и общим объемом продаж. Поскольку таблица COFFEE_HOUSES имеет сотни строк, эти сравнения будут быстрее и легче, если искавший объем данных будет сокращен к только тем строкам где значение в столбце STORE_ID указывает на Калифорнию.

Это - точно вид проблемы это a FilteredRowSet возразите адресам, обеспечивая следующие возможности:

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

Определение Фильтрации Критериев в Объектах Предиката

Установить критерии для который строки в a FilteredRowSet объект будет видим, Вы определяете class, который реализует Predicate интерфейс. Объект, создаваемый с этим class, инициализируется со следующим:

Отметьте, что диапазон значений является содержащим, означая, что значение на границе включается в диапазон. Например, если у диапазона есть верхний уровень 100 и нижний уровень 50, значение 50, как полагают, в пределах диапазона. Значение 49 не. Аналогично, 100 в пределах диапазона, но 101 не.

В соответствии со сценарием, где владелец хочет сравнить Калифорнийские хранилища, реализацию Predicate интерфейс, который фильтрует для кофеен Перерыва на кофе, расположенных в Калифорнии, должен быть записан. Нет никого правильного способа сделать это, что означает, что есть большая широта в том, как реализация пишется. Например, Вы могли назвать class и его элементы вообще, Вы хотите и реализуете конструктора, и эти три оценивают методы всегда, который выполняет требуемые результаты.

Таблица, перечисляющая все кофейни, названные COFFEE_HOUSES, имеет сотни строк. Чтобы сделать вещи более управляемыми, этот пример использует таблицу с гораздо меньшим количеством строк, которой является достаточно, чтобы демонстрировать, как фильтрация делается.

Значение в столбце STORE_ID int значение, которое указывает, между прочим, на состояние, в котором располагается кофейня. Значение, начинающееся 10, например, средства, что состоянием является Калифорния. STORE_ID значения, начинающиеся 32, указывают на Орегон, и те, которые начинают 33, указывают на штат Вашингтон.

Следующий class StateFilter реализации Predicate интерфейс:

public class StateFilter implements Predicate {

    private int lo;
    private int hi;
    private String colName = null;
    private int colNumber = -1;

    public StateFilter(int lo, int hi, int colNumber) {
        this.lo = lo;
        this.hi = hi;
        this.colNumber = colNumber;
    }

    public StateFilter(int lo, int hi, String colName) {
        this.lo = lo;
        this.hi = hi;
        this.colName = colName;
    }

    public boolean evaluate(Object value, String columnName) {
        boolean evaluation = true;
        if (columnName.equalsIgnoreCase(this.colName)) {
            int columnValue = ((Integer)value).intValue();
            if ((columnValue >= this.lo)
                &&
                (columnValue <= this.hi)) {
                evaluation = true;
            } else {
                evaluation = false;
            }
        }
        return evaluation;
    }

    public boolean evaluate(Object value, int columnNumber) {

        boolean evaluation = true;

        if (this.colNumber == columnNumber) {
            int columnValue = ((Integer)value).intValue();
            if ((columnValue >= this.lo)
                &&
                (columnValue <= this.hi)) {
                evaluation = true;
            } else {
                evaluation = false;
            }
        }
        return evaluation;
    }


    public boolean evaluate(RowSet rs) {
    
        CachedRowSet frs = (CachedRowSet)rs;
        boolean evaluation = false;

        try {
            int columnValue = -1;

            if (this.colNumber > 0) {
                columnValue = frs.getInt(this.colNumber);
            } else if (this.colName != null) {
                columnValue = frs.getInt(this.colName);
            } else {
                return false;
            }

            if ((columnValue >= this.lo)
                &&
                (columnValue <= this.hi)) {
                evaluation = true;
            }
        } catch (SQLException e) {
            JDBCTutorialUtilities.printSQLException(e);
            return false;
        } catch (NullPointerException npe) {
            System.err.println("NullPointerException caught");
            return false;
        }
        return evaluation;
    }
}

Это - очень простая реализация, которая проверяет значение в столбец, определенный также colName или colNumber видеть, находится ли это в диапазоне lo к hi, включительно. Следующая строка кода, от FilteredRowSetSample, создает фильтр, который позволяет только строки где STORE_ID значение столбца указывает на значение между 10000 и 10999, который указывает на Калифорнийское расположение:

StateFilter myStateFilter = new StateFilter(10000, 10999, 1);

Отметьте что StateFilter class, только определенный, применяется к одному столбцу. Возможно иметь это, применяются к двум или больше столбцам, делая каждый из массивов параметров вместо единственных значений. Например, конструктор для a Filter объект мог быть похожим на следующее:

public Filter2(Object [] lo, Object [] hi, Object [] colNumber) {
    this.lo = lo;
    this.hi = hi;
    this.colNumber = colNumber;
}

Первый элемент в colNumber объект дает первый столбец, в котором значение будет проверено по первому элементу в lo и первый элемент в hi. Значение во втором столбце, обозначенном colNumber будет проверен по вторым элементам в lo и hi, и так далее. Поэтому, число элементов в трех массивах должно быть тем же самым. Следующий код что реализация метода evaluate(RowSet rs) мог бы быть похожим для a Filter2 объект, в котором параметры являются массивами:

public boolean evaluate(RowSet rs) {
    CachedRowSet crs = (CachedRowSet)rs;
    boolean bool1;
    boolean bool2;
    for (int i = 0; i < colNumber.length; i++) {

        if ((rs.getObject(colNumber[i] >= lo [i]) &&
            (rs.getObject(colNumber[i] <= hi[i]) {
            bool1 = true;
        } else {
            bool2 = true;
        }

        if (bool2) {
            return false;
        } else {
            return true;
        }
    }
}

Преимущество использования a Filter2 реализация состоит в том, что можно использовать параметры любого Object введите и может проверить один столбец или многократные столбцы, не имея необходимость писать другую реализацию. Однако, следует передать Object введите, что означает, что следует преобразовать тип примитива в Object ввести. Например, если Вы используете int значение для lo и hi, следует преобразовать int оцените Integer объект прежде, чем передать это конструктору. String объекты уже Object типы, таким образом, Вы не должны преобразовать их.

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

Ссылочная реализация для FilteredRowSet интерфейс, FilteredRowSetImpl, включает конструктора по умолчанию, который используется в следующей строке кода, чтобы создать пустое FilteredRowSet объект frs:.

FilteredRowSet frs = new FilteredRowSetImpl();

Реализация расширяется BaseRowSet абстрактный class, таким образом, frs объекту определили свойства значения по умолчанию в BaseRowSet. Это означает это frs с возможностью прокрутки, обновляем, не показывает удаленные строки, имеет включенную обработку escape, и так далее. Кроме того, потому что FilteredRowSet интерфейс является подынтерфейсом CachedRowSet, Joinable, и WebRowSet, frs у объекта есть возможности каждого. Это может работать как разъединенный RowSet возразите, может быть часть a JoinRowSet объект, и может читать и записать себя в формате XML.

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

Можно использовать экземпляр RowSetFactory, который создается из class RowSetProvider, создать a FilteredRowSet объект. См. Используя Интерфейс RowSetFactory в Использовании Объектов JdbcRowSet для получения дополнительной информации.

Как другой разъединенный RowSet объекты, frs объект должен заполнить себя с данными из источника табличных данных, который является реляционной базой данных в ссылочной реализации. Следующий фрагмент кода от FilteredRowSetSample устанавливает свойства, необходимые, чтобы соединиться с базой данных, чтобы выполнить ее команду. Отметьте, что этот код использует DriverManager class, чтобы сделать соединение, которое делается для удобства. Обычно, лучше использовать a DataSource объект, который был зарегистрирован в службе именования, которая реализует Интерфейс Именования и Каталога Java (JNDI):

frs.setCommand("SELECT * FROM COFFEE_HOUSES");
frs.setUsername(settings.userName);
frs.setPassword(settings.password);
frs.setUrl(settings.urlString);

Следующая строка кода заполняет frs objectwith данные, хранившие в COFFEE_HOUSE таблица:

frs.execute();

Метод execute делает все виды вещей в фоновом режиме, обращаясь RowSetReader объект для frs, то, который создает соединение, выполняет команду для frs, заполняет frs с данными от ResultSet объект, который производится, и закрывает соединение. Отметьте это если таблица COFFEE_HOUSES имел больше строк чем frs объект мог содержать в памяти когда-то, CachedRowSet методы оповещения использовались бы.

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

Создание и Установка Объектов Предиката

Теперь, когда FilteredRowSet объект frs содержит список установлений Перерыва на кофе, можно установить критерии отбора для того, чтобы сузить число строк в frs объект, которые видимы.

Следующая строка кода использует StateFilter class, определенный ранее, чтобы создать объект myStateFilter, который проверяет столбец STORE_ID определить, какие хранилища находятся в Калифорнии (хранилище находится в Калифорнии, если ее Идентификационный номер между 10000 и 10999, включительно):

StateFilter myStateFilter = new StateFilter(10000, 10999, 1);

Следующие наборы строки myStateFilter как фильтр для frs.

frs.setFilter(myStateFilter);

Чтобы сделать фактическую фильтрацию, Вы вызываете метод next, который в ссылочной реализации вызывает соответствующую версию Predicate.evaluate метод, который Вы реализовали ранее.

Если возвращаемое значение true, строка будет видима; если возвращаемое значение false, строка не будет видима.

Установка Объектов FilteredRowSet с Новым Предикатом Возражает, чтобы Фильтровать Данные Далее

Вы устанавливаете многократные фильтры последовательно. В первый раз Вы вызываете метод setFilter и передайте это a Predicate объект, Вы применили критерии фильтрации в том фильтре. После вызова метода next на каждой строке, которая делает видимым только те строки, которые удовлетворяют фильтр, можно вызвать setFilter снова, передавая это различное Predicate объект. Даже при том, что только один фильтр устанавливается за один раз, эффект состоит в том, что оба фильтра применяются кумулятивно.

Например, владелец получил список хранилищ Перерыва на кофе в Калифорнии, устанавливая stateFilter как Predicate объект для frs. Теперь владелец хочет сравнить хранилища в двух Калифорнийских городах, Сан-Франциско (SF в таблице COFFEE_HOUSES) и Лос-Анджелес (LA в таблице). Первое, что нужно сделать состоит в том, чтобы записать a Predicate реализация, которая фильтрует для хранилищ или в SF или в LA:

public class CityFilter implements Predicate {

    private String[] cities;
    private String colName = null;
    private int colNumber = -1;

    public CityFilter(String[] citiesArg, String colNameArg) {
        this.cities = citiesArg;
        this.colNumber = -1;
        this.colName = colNameArg;
    }

    public CityFilter(String[] citiesArg, int colNumberArg) {
        this.cities = citiesArg;
        this.colNumber = colNumberArg;
        this.colName = null;
    }

    public boolean evaluate Object valueArg, String colNameArg) {

        if (colNameArg.equalsIgnoreCase(this.colName)) {
            for (int i = 0; i < this.cities.length; i++) {
                if (this.cities[i].equalsIgnoreCase((String)valueArg)) {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean evaluate(Object valueArg, int colNumberArg) {

        if (colNumberArg == this.colNumber) {
            for (int i = 0; i < this.cities.length; i++) {
                if (this.cities[i].equalsIgnoreCase((String)valueArg)) {
                    return true;
                }
            }
        }
        return false;
    }


    public boolean evaluate(RowSet rs) {

        if (rs == null) return false;

        try {
            for (int i = 0; i < this.cities.length; i++) {

                String cityName = null;

                if (this.colNumber > 0) {
                    cityName = (String)rs.getObject(this.colNumber);
                } else if (this.colName != null) {
                    cityName = (String)rs.getObject(this.colName);
                } else {
                    return false;
                }

                if (cityName.equalsIgnoreCase(cities[i])) {
                    return true;
                }
            }
        } catch (SQLException e) {
            return false;
        }
        return false;
    }
}

Следующий фрагмент кода от FilteredRowSetSample устанавливает новый фильтр и выполняет итерации через строки в frs, распечатывание строк, где CITY столбец содержит или SF или ЛА. Отметьте это frs в настоящий момент содержит только строки, где хранилище находится в Калифорнии, таким образом, критерии Predicate объект state все еще в действительности, когда фильтр изменяется на другого Predicate объект. Код, который следует, устанавливает фильтр к CityFilter объект city. CityFilter реализация использует массивы в качестве параметров конструкторам, чтобы иллюстрировать, как это может быть сделано:

public void testFilteredRowSet() {

    FilteredRowSet frs = null;
    StateFilter myStateFilter = new StateFilter(10000, 10999, 1);
    String[] cityArray = { "SF", "LA" };

    CityFilter myCityFilter = new CityFilter(cityArray, 2);

    try {
        frs = new FilteredRowSetImpl();

        frs.setCommand("SELECT * FROM COFFEE_HOUSES");
        frs.setUsername(settings.userName);
        frs.setPassword(settings.password);
        frs.setUrl(settings.urlString);
        frs.execute();

        System.out.println("\nBefore filter:");
        FilteredRowSetSample.viewTable(this.con);

        System.out.println("\nSetting state filter:");
        frs.beforeFirst();
        frs.setFilter(myStateFilter);
        this.viewFilteredRowSet(frs);

        System.out.println("\nSetting city filter:");
        frs.beforeFirst();
        frs.setFilter(myCityFilter);
        this.viewFilteredRowSet(frs);
    } catch (SQLException e) {
        JDBCTutorialUtilities.printSQLException(e);
    }
}

Вывод должен содержать строку для каждого хранилища, которое находится в Сан-Франциско, Калифорнии или Лос-Анджелесе, Калифорния. Если была строка в который CITY столбец содержавший LA и STORE_ID столбец, содержавший 40003, это не было бы включено в список, потому что это было уже отфильтровано, когда фильтр был установлен к state. (40003 не находится в диапазоне 10000 - 10999.)

Обновление Объектов FilteredRowSet

Можно произвести изменение в a FilteredRowSet возразите, но только если то изменение не нарушает ни одного из критериев фильтрации в настоящий момент в действительности. Например, можно вставить новую строку или изменить одно или более значений в существующей строке, если новое значение или значения в пределах критериев фильтрации.

Вставка или Обновление Строк

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

Текущее состояние frs объект состоит в том что StateFilter объект был установлен и затем CityFilter объект был установлен. В результате frs в настоящий момент делает видимым только те строки, которые удовлетворяют критерии для обоих фильтров. И, одинаково важный, невозможно добавить строку к frs возразите, если это не удовлетворяет критерии для обоих фильтров. Следующий фрагмент кода пытается вставить две новых строки в frs объект тот, одна строка, в который значения в STORE_ID и CITY столбцы и соответствуют критериям, и одной строке в который значение в STORE_ID не передает фильтр, но значение в CITY столбец делает:

frs.moveToInsertRow();
frs.updateInt("STORE_ID", 10101);
frs.updateString("CITY", "SF");
frs.updateLong("COF_SALES", 0);
frs.updateLong("MERCH_SALES", 0);
frs.updateLong("TOTAL_SALES", 0);
frs.insertRow();

frs.updateInt("STORE_ID", 33101);
frs.updateString("CITY", "SF");
frs.updateLong("COF_SALES", 0);
frs.updateLong("MERCH_SALES", 0);
frs.updateLong("TOTAL_SALES", 0);
frs.insertRow();
frs.moveToCurrentRow();

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

Удаляя Все Фильтры, таким образом, Все Строки Видимы

Владелец может добавить хранилище в Вашингтоне, аннулируя фильтр. Без набора фильтра, всех строк в frs объект еще раз видим, и хранилище в любом расположении может быть добавлено к списку хранилищ. Следующая строка кода сбрасывает текущий фильтр, эффективно аннулируя оба из Predicate реализации, ранее установленные на frs объект.

frs.setFilter(null);

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

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

Например, учитывая, что метод setFilter был только что вызван с нулем параметра, нет никакого набора фильтра на frs объект. Это означает, что все строки видимы и могут поэтому быть удалены. Однако, после StateFilter объект myStateFilter был установлен, который отфильтровывал любое состояние кроме Калифорнии, только хранилища, расположенные в Калифорнии, могли быть удалены. Когда CityFilter объект myCityFilter был установлен для frs объект, только кофейни в Сан-Франциско, Калифорнии или Лос-Анджелесе, Калифорния могла быть удалена, потому что они были в единственных видимых строках.


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

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



Spec-Zone.ru - all specs in one place