При реализации функционала приложения, работающего с реляционной базой данных, используются следующие программные элементы библиотеки avalanche-sql:
Класс | Назначение |
---|---|
ru.funsys.avalanche.sql.Database | Основной объект выполнения SQL выражений |
ru.funsys.avalanche.sql.Adapter | Адаптер (java интерфейс), используется для получения ссылки на объект Database |
ru.funsys.avalanche.sql.annotation.Column | Аннотация, описывающая связь поля класса (типа данных) с колонкой таблицы |
ru.funsys.avalanche.sql.Query | Класс запроса, содержащий SQL выражения и параметры запроса |
ru.funsys.avalanche.sql.QueryType | Класс запроса, содержащий SQL выражения, возвращаемый тип и параметры запроса |
ru.funsys.avalanche.sql.QueryProcedure | Класс запроса, содержащий SQL выражение вызова процедуры и описание входных и выходных параметров |
ru.funsys.avalanche.sql.InOutParameter | Класс, описывающий входной и/или выходной параметр процедуры |
ru.funsys.avalanche.sql.ExecuteSet | Класс, содержащий результат выполнения множества SQL выражений в одной транзакции |
Класс ru.funsys.avalanche.sql.Database представляет собой абстракцию над источником данных (javax.sql.DataSource) и явно в коде приложения не используется. Для доступа к классу ru.funsys.avalanche.sql.Database требуется адаптер ru.funsys.avalanche.sql.Adapter, поле которого должно присутствовать в коде класса, а в конфигурации приложения должно присутствовать секция адаптера.
Адаптер ru.funsys.avalanche.sql.Adapter используется для определения связи с экземпляром класса ru.funsys.avalanche.sql.Database, который может быть определен в конфигурации приложения или находиться на удаленной машине. Адаптер ru.funsys.avalanche.sql.Adapter упрощает программный код приложения, освобождая программиста от работы с соединениями БД, управления транзакциями, повышает модифицируемость приложения.
Адаптер ru.funsys.avalanche.sql.Adapter может быть определен в классе, наследуемом от класса ru.funsys.avalanche.Application.
Пример
public class MyApplication extends Application { @CfgAtribute(description="Адаптер доступа к БД") Adapter database; ... }
Выполнить запрос SELECT c подставляемыми параметрами.
Пример без параметров
try { ResultSet resultSet = database.select("SELECT * FROM ... "); while (resultSet.next()) { // обработка полученного результата ... } } catch (Exception e) { // обработка возможного исключения ... }
Пример c параметрами
try { Timestamp timestamp = new Timestamp(); ResultSet resultSet = database.select("SELECT * FROM ... WHERE user_name = ? AND date_start < ?", "Петр", timestamp); while (resultSet.next()) { // обработка полученного результата ... } } catch (Exception e) { // обработка возможного исключения ... }
Выполнить запрос SELECT c подставляемыми параметрами и получить результат заданного типа.
Пример без параметров
try { Task[] allTasks = database.select("SELECT * FROM ... ", Task.class); // обработка полученного результата ... } catch (Exception e) { // обработка возможного исключения ... }
Пример c параметрами
try { Timestamp timestamp = new Timestamp(); Task[] tasks = database.select("SELECT * FROM ... WHERE user_name = ? AND date_start < ?", Task.class, "Петр", timestamp); // обработка полученного результата ... } catch (Exception e) { // обработка возможного исключения ... }
Выполнить запрос SELECT c подставляемыми из вектора параметрами.
Пример
try { Vector<Object> vector = new Vector(); vector.add(Петр"); vector.add(new Timestamp()); ResultSet resultSet = database.select("SELECT * FROM ... WHERE user_name = ? AND date_start < ?", vector); while (resultSet.next()) { // обработка полученного результата ... } } catch (Exception e) { // обработка возможного исключения ... }
Выполнить запрос SELECT c подставляемыми из вектора параметрами.
Пример
try { List<Object> list = new ArrayList<Object>(); list.add(Петр"); list.add(new Timestamp()); ResultSet resultSet = database.select("SELECT * FROM ... WHERE user_name = ? AND date_start < ?", list); while (resultSet.next()) { // обработка полученного результата ... } } catch (Exception e) { // обработка возможного исключения ... }
Выполнить запрос SELECT с использованием экземпляра класса Query.
Пример
try { Query query = new Query("SELECT * FROM ... WHERE user_name = ? AND date_start < ?", "Петр", new Timestamp()); ResultSet resultSet = database.select(query); while (resultSet.next()) { // обработка полученного результата ... } } catch (Exception e) { // обработка возможного исключения ... }
Выполнить запрос SELECT с использованием экземпляра класса QueryType.
Пример
try { QueryType queryType = new QueryType("SELECT * FROM ... WHERE user_name = ? AND date_start < ?", Task.class, "Петр", new Timestamp()); Task[] tasks = database.select(queryType); // обработка полученного результата ... } catch (Exception e) { // обработка возможного исключения ... }
Выполнить несколько запросов в параллельных потоках. Этот метод возвращает массив объектов. Каждый элемент этого массива содержит либо результат выполнения запроса, либо исключение, возникшее при выполнении запроса
try { Query[] queries = new Query[3]; queries[0] = new Query("SELECT * FROM ... WHERE ...", параметр_1, параметр_2, ..., параметр_N); queries[1] = new QueryType("SELECT * FROM ... WHERE user_name = ? AND date_start < ?", Task.class, "Петр", new Timestamp()); queries[2] = new Query("SELECT * FROM ... WHERE ... ORDER BY ...", , параметр_1, параметр_2, ..., параметр_Y); Object[] result = database.select(queries); // обработка полученного результата ... } catch (Exception e) { // обработка возможного исключения ... }
Выполнить запрос модификации (INSERT, UPDATE, DELETE). Возвращается число вставленных, измененных или удаленных записей
Примеры
try { database.execute("INSERT INTO ... (user_name, ...) VALUES (?, ...)", "Петр", ... ); } catch (Exception e) { // обработка возможного исключения ... }
try { int count = database.execute("DELETE FROM ... WHERE user_name = ?", "Петр"); ... } catch (Exception e) { // обработка возможного исключения ... }
Выполнить запрос модификации (INSERT, UPDATE, DELETE). Вектор подставляемых в запрос параметров, размер вектора параметров должен быть равен числу знаков вопроса в sql запросе. Если нет параметров запроса, то может быть null.
Примеры
try { Vector<Object> vector = new Vector<Object>(); vector.add("Петр"); vector.add(...); ... database.execute("INSERT INTO ... (user_name, ...) VALUES (?, ...)", vector); } catch (Exception e) { // обработка возможного исключения ... }
try { Vector<Object> vector = new Vector<Object>(); vector.add("Петр"); int count = database.execute("DELETE FROM ... WHERE user_name = ?", vector); ... } catch (Exception e) { // обработка возможного исключения ... }
Выполнить запрос модификации (INSERT, UPDATE, DELETE). Список подставляемых в запрос параметров, размер вектора параметров должен быть равен числу знаков вопроса в sql запросе. Если нет параметров запроса, то может быть null.
Примеры
try { List<Object> list = new ArrayList<Object>(); list.add("Петр"); list.add(...); ... database.execute("INSERT INTO ... (user_name, ...) VALUES (?, ...)", list); } catch (Exception e) { // обработка возможного исключения ... }
try { List<Object> list = new ArrayList<Object>(); list.add("Петр"); int count = database.execute("DELETE FROM ... WHERE user_name = ?", list); ... } catch (Exception e) { // обработка возможного исключения ... }
Выполнить запрос модификации (INSERT, UPDATE, DELETE) с использованием экземпляра класса Query..
Примеры
try { List<Object> list = new ArrayList<Object>(); list.add("Петр"); list.add(...); Query query = new Query("INSERT INTO ... (user_name, ...) VALUES (?, ...)", list); database.execute(query); } catch (Exception e) { // обработка возможного исключения ... }
try { List<Object> list = new ArrayList<Object>(); list.add("Петр"); Query query = new Query("DELETE FROM ... WHERE user_name = ?", list); int count = database.execute(query); ... } catch (Exception e) { // обработка возможного исключения ... }
Выполнить множество запросов модификации (INSERT, UPDATE, DELETE) в одной транзакции. Уровень изоляции определяется либо в СУБД (действующий по умолчанию), либо в конфигурации объекта приложения ru.funsys.avalanche.sql.Database. Ошибка выполнения любого запроса откатывает всю транзакцию. Возвращает массив объектов, содержащих число модифицированных записей и время выполнения каждого запроса
Пример
try { Query query1 = new Query("INSERT INTO ... VALUES (?, ?, ...)", param11, param12, ...); Query query2 = new Query("UPDATE ... ?, ? ...", param21, param22, ...); Query query3 = new Query("DELETE FROM ... WHERE ... = ? AND ... = ? ...", param31, param32, ...); ExecuteSet[] executeSet = database.execute(query1, query2, query3); // При необходимости контроль результата } catch (Exception e) { // обработка возможного исключения ... }
Выполнить множество запросов модификации (INSERT, UPDATE, DELETE) в одной транзакции. Уровень изоляции определяется либо в СУБД (действующий по умолчанию), либо конфигурации объекта приложения ru.funsys.avalanche.sql.Database. Ошибка выполнения любого запроса откатывает всю транзакцию. Возвращает массив объектов, содержащих число модифицированных записей и время выполнения каждого запроса
Пример
try { List<Query> transaction = new ArrayList<Query>(); list.add(new Query("INSERT INTO ... VALUES (?, ?, ...)", param11, param12, ...)); list.add(new Query("UPDATE ... ?, ? ...", param21, param22, ...); list.add(new Query("DELETE FROM ... WHERE ... = ? AND ... = ? ...", param31, param32, ...)); ExecuteSet[] executeSet = database.execute(list); // При необходимости контроль результата } catch (Exception e) { // обработка возможного исключения ... }
Выполнить множество запросов модификации (INSERT, UPDATE, DELETE) в одной транзакции. Уровень изоляции определяется либо в СУБД (действующий по умолчанию), либо в конфигурации объекта приложения ru.funsys.avalanche.sql.Database. При установленном параметре ignore в значении true ошибки выполнения любого запроса игнорируются. Возвращает массив объектов, содержащих число модифицированных записей и время выполнения каждого запроса
Пример
try { Query query1 = new Query("INSERT INTO ... VALUES (?, ?, ...)", param11, param12, ...); Query query2 = new Query("UPDATE ... ?, ? ...", param21, param22, ...); Query query3 = new Query("DELETE FROM ... WHERE ... = ? AND ... = ? ...", param31, param32, ...); ExecuteSet[] executeSet = database.execute(true, query1, query2, query3); // При необходимости контроль результата } catch (Exception e) { // обработка возможного исключения ... }
Метод получения метаданных базы. Передаваемые параметры могут быть чувствительны к регистру в используемой СУБД. Для настройки регистра используется конфигурационный параметр ru.funsys.avalanche.sql.Database.
Пример получения структуры таблицы
try { String schema = ...; String table = ...; ResultSet resultSet = database.metadata("getColumns", null, schema, table, (String) null); while (resultSet.next()) { // Обработка результата ... } } catch (Exception e) { // обработка возможного исключения ... }
Вызов хранимой процедуры
Пример
try { database.call("call ...", new InOutParameter(Types.INTEGER, idAuthor), new InOutParameter(Types.INTEGER, idProgramm), new InOutParameter(Types.VARCHAR, message)); } catch (Exception e) { logger.error("Ошибка вызова хранимой процедуры", e); }
Вызов хранимой процедуры
Пример
try { QueryProcedure queryProcedure = new QueryProcedure("call ...", new InOutParameter(Types.INTEGER, idAuthor), new InOutParameter(Types.INTEGER, idProgramm), new InOutParameter(Types.VARCHAR, message)) database.call(queryProcedure); } catch (Exception e) { logger.error("Ошибка вызова хранимой процедуры", e); }
Аннотация, описывающая связь поля класса (типа данных) с колонкой таблицы или результата
При выполнении SQL запросов, которые возвращают типизированные данные, происходит автоматическое связывание поля класса с колонкой таблицы/результата по имени (имя поля класса совпадает с именем колонки таблицы или результата и SQL тип может быть преобразован в тип поля класса). В тех случаях, когда по каким либо причинам поле класса не совпадает с именем поля таблицы/результата, используют аннотацию @Column для задания связи.
Пример использования. Требуется выполнить SQL запрос, в результате которого возвращается колонка user_name. Значения колонки user_name требуется установить в поле name экземпляров класса User.
SELECT user_name, ... FROM ...
У поля name класса User требуется объявить аннотацию @Column, в которой указывается имя колонки полученного результата
public class User { @Column(name="user_name") public String name; ... }
Получение результата
... User[] users = database.select("SELECT user_name, ... FROM ...", User.class, ....) ...или
... QueryType queryType = new QueryType("SELECT user_name, ... FROM ...", User.class, ....); User[] users = database.select(queryType); ...
Класс-оболочка определения параметров SQL запроса. Имеет несколько вариантов конструктора.
/** * Создать объект запроса * * @param statement SQL выражение * * @param parameters параметры запроса */ public Query(String statement, Object... parameters) /** * Создать объект запроса * * @param statement statement SQL выражение * @param parameters параметры запроса */ public Query(String statement, Vector<Object> parameters) /** * Создать объект запроса * * @param statement statement SQL выражение * @param parameters параметры запроса */ public Query(String statement, List<Object> parameters)
Класс-оболочка определения параметров SQL запроса получения типизированного результата. Имеет несколько вариантов конструктора.
/** * @param statement SQL выражение * @param type тип возвращаемых записей * @param parameters параметры запроса */ public QueryType(String statement, Class<?> type, Object... parameters) /** * @param statement SQL выражение * @param type тип возвращаемых записей * @param parameters параметры запроса */ public QueryType(String statement, ArrayList<Object> parameters, Class<?> type)
Класс-оболочка определения параметров вызова хранимой процедуры. Имеет несколько вариантов конструктора.
/** * Создать объект запроса * * @param statement SQL выражение * * @param parameters параметры запроса */ public QueryProcedure(String statement, InOutParameter... parameters) /** * Создать объект запроса * * @param statement statement SQL выражение * @param parameters параметры запроса */ public QueryProcedure(String statement, Vector<InOutParameter> parameters) /** * Создать объект запроса * * @param statement statement SQL выражение * @param parameters параметры запроса */ public QueryProcedure(String statement, ArrayList<InOutParameter> parameters)
Класс-оболочка определения параметров хранимой процедуры. Имеет несколько вариантов конструктора. При задании типа параметра используется значения: 0 - IN, 1 - INOUT, 2 - OUT.
/** * Создает выходной параметр * * @param sqlType SQL тип параметра */ public InOutParameter(int sqlType) /** * Создает входной параметр * * @param sqlType SQL тип параметра * @param value значение входного параметра */ public InOutParameter(int sqlType, Object value) /** * Создает входной/выходной параметр * * @param type тип параметра (0 - IN, 1 - INOUT, 2 - OUT) * @param sqlType SQL тип параметра * @param value значение входного параметра */ public InOutParameter(int type, int sqlType, Object value)
Класс-оболочка возвращаемого результата. Этот класс позволяет получить доступ к результатам выполнения запросов в транзакции.
public class ExecuteSet { /** * Время выполнения запроса */ private long timer; /** * Количество модифицированных записей */ private int records; /** * Результат генерации ключей при вставке записей */ private ResultSet keys; /** * Полученный типизированный результат запроса */ private Object[] rows; /** * Полученный результат запроса */ private ResultSet resultSet; /** * Исключение, возникшее при выполнении выражения */ private java.sql.SQLException exception = null; public long getTimer() { return timer; } public int getRecords() { return records; } public ResultSet getKeys() { return keys; } public void setKeys(ResultSet keys) { this.keys = keys; } public Object[] getRows() { return rows; } public void setRows(Object[] rows) { this.rows = rows; } public ResultSet getResultSet() { return resultSet; } public void setResultSet(ResultSet resultSet) { this.resultSet = resultSet; } public boolean isError() { return exception != null; } public java.sql.SQLException getError() { return exception; } }