13. Лекция: Реализация доступа к базам данных в среде JBUILDER и среде JDEVELOPER

Рассматриваются механизмы доступа к базам данных из про-грамм на языке Java посредством JDBC и SQLJ, описывается применение моста JDBC:ODBC.

Работа с базами данных

Язык Java позволяет реализовывать два механизма доступа к базам данных:

  • с применением средств JDBC;
  • с использованием SQLJ.

При реализации доступа через JDBC могут использоваться:

  • JDBC-драйверы;
  • мост JDBC-ODBC.

При реализации доступа через SQLJ SQL-операторы встраиваются непосредственно в код на языке Java, а затем обрабатываются SQLJ-предкомпилятором. Обычный SQLJ-предкомпилятор ограничивает синтаксис встраиваемых SQL-операторов стандартом SQL-92. Однако при применении SQLJ-предкомпиляторов, ориентированных на конкретные СУБД, допускается использование конструкций языка SQL, реализуемых в этих СУБД. Так, SQLJ-предкомпилятор для Oracle 9i позволяет не только статическое, но и динамическое встраивание SQL-операторов.

Реализация доступа к базам данных в среде JBUILDER

При создании программ на языке Java можно придерживаться "чистого" Java, что ограничивает возможности программиста использованием только классов и интерфейсов пакетов JDK. Однако, различные существующие среды программирования, включая и JBuilder, значительно расширяют возможности программиста, предоставляя дополнительные библиотеки классов. Далее будут рассмотрены классы и интерфейсы, применяемые для реализации доступа к базам данных как из пакетов JDK, так и предоставляемые средой JBuilder.

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

JBUILDER позволяет реализовывать доступ к базам данных с применением драйверов JDBC и с использованием моста JDBC-ODBC, реализующего непосредственный доступ к базе данных через ODBC-драйверы. Мост JDBC-ODBC может быть использован и в том случае, если JDBC-драйвер для базы данных отсутствует.

На следующей схеме представлен механизм взаимодействия компонентов, реализующих работу с базой данных.


Преимущество доступа с использованием JDBC-драйвера заключается в том, что нет необходимости устанавливать эти драйверы на каждой клиентской машине (в отличие от ODBC-драйверов, которые предварительно должны быть зарегистрированы на каждом клиенте).

Для реализации доступа к любому источнику данных в приложение должен быть добавлен компонент, представляющий связь с конкретным источником данных. К таким компонентам относятся:

  • Connection - интерфейс из пакета java.sql, используемый для соединения с источником данных.
  • Database - используется для указания класса драйвера и местоположения базы данных.
  • TextDataFile - указывает используемый текстовый файл.
  • DataStore - для доступа к базе данных DataStore.

Компоненты, представляющие в приложении структуру извлекаемых данных, называются наборами данных. К таким компонентам относятся:

  • ResultSet - набор данных для "чистого" Java.
  • TableDataSet - позволяет указать имя таблицы или имя текстового файла, представляющих источник данных, и определить параметры столбцов набора данных (тип, размер, значение по умолчанию, заголовок и т.д.).
  • QueryDataSet - используется для определения набора данных в терминах SQL-оператора.

Приложение может содержать компоненты, предназначенные для отображения информации из набора данных. Страница dbSwing палитры компонентов окна дизайнера содержит визуальные компоненты, специально предназначенные для отображения набора данных (эти классы не входят в JDK). К таким компонентам относятся:

  • JdbCheckBox - флажок.
  • JdbRadioButton - переключатель (радиокнопка).
  • JdbTextField - текстовое поле.
  • JdbComboBox - раскрывающийся список.
  • JdbSlider - бегунок
  • JdbTextPane - многострочное текстовое поле
  • JdbToggleButton - кнопка переключатель
  • JdbLabel - надпись
  • JdbTable - таблица
  • JdbTree - дерево.
  • JdbList - список значений поля текущей записи.

Для навигации по полям и записям набора данных можно использовать компонент JdbNavToolBar,


который предоставляет стандартный интерфейс, включающий возможность перехода от записи к записи, переход к первой и последней записи, добавление и удаление записи, отмена изменений, выполненных над текущей записью, обновление набора данных и фиксация сделанных изменений. Для изменения предусмотренного по умолчанию поведения кнопок компонента JdbNavToolBar можно:

  • создать производный класс и переопределить метод обработки сообщений actionPerformed();
  • получить ссылку на кнопку компонента и удалить в JdbNavToolBar ActionListener для кнопки, а затем добавить свой ActionListener.

Для определения текущего набора данных, используемого компонентом, следует вызвать метод getFocusedDataSet().

Дополнительно пакет com.borland.dbswing предоставляет компоненты, которые также могут использоваться для навигации по набору данных, включая:

  • JdbNavField - компонент, наследуемый от JTextField, и позволяющий выполнять поиск в наборе данных введенного значения, и при нахождении его делать найденную запись текущей. Набор данных, в котором выполняется поиск, определяется свойством dataSet, а столбец - свойством columnName. Если свойство columnName не указано, то используется столбец в таблице JdbTable, имеющий фокус, а если такого столбца нет - то первый столбец набора данных;
  • JdbNavComboBox и JdbNavList - компоненты, отображающие список значений столбца набора данных; при выборе элемента списка данная запись становится текущей. Набор данных, по которому выполняется навигация, определяется свойством dataSet, а столбец - свойством columnName (а при отсутствии значения данного свойства - так же как и для компонента JdbNavField);
  • JdbNavTree - компонент, наследуемый от JTree и позволяющий устанавливать текущей записью запись, выбранную в данном компоненте. Отображаемые значения определяются значениями свойств dataSet и columnName.

Работа с текстовыми файлами

JBUILDER предоставляет компонент "текстовый файл" - TextDataFile, который используется для импортирования данных из текстового файла и экспортирования их обратно.

Компонент набора данных реализуется классом TableDataSet. Он используется для хранения данных, импортируемых из текстового файла. Если для текстового файла существует одноименный файл с расширением SHEMA, то структуру столбцов описывать нет необходимости. Такой файл автоматически создается компонентом TableDataSet при записи в текстовый файл и содержит описание столбцов и другую информацию по набору данных. Для каждого столбца набора данных создается объект типа Column.

В следующем примере иллюстрируется чтение данных из текстового файла и их отображение в компоненте типа JdbTable:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.borland.dx.dataset.*;
import com.borland.dbswing.*;
public class Frame1 extends JFrame {
         // contentPane - контейнер для размещения
        // визуальных компонентов
  JPanel contentPane;
  BorderLayout borderLayout1 = new BorderLayout(); 
      // Компонент TextDataFile со страницы DataExpress
     // для работы с текстовым файлом - источником данных
  TextDataFile textDataFile1 = new TextDataFile();	  
   // Компонент TableDataSet со страницы DataExpress, 
       // реализующий набор данных
  TableDataSet tableDataSet1 = new TableDataSet();   
  Column column1 = new Column();	  // Создается для 
                      // каждого столбца в наборе данных
  Column column2 = new Column();
  Column column3 = new Column();
  TableScrollPane tableScrollPane1 = new TableScrollPane();
      		// Компонент "таблица для набора данных"
  JdbTable jdbTable1 = new JdbTable();	 
  public Frame1() {				// Конструктор
                  // Определение прослушиваемых событий
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try {      jbInit();    }    
    catch(Exception e) { e.printStackTrace();  }
  }
private void jbInit() throws Exception  {
    column2.setCaption("Столбец2");   //Отображаемый 
                                                   // заголовок столбца
    column2.setColumnName("NewColumn2");  //Имя столбца
    column3.setCaption("Столбец3");
    column3.setColumnName("NewColumn3");  
    column1.setCaption("Столбец1");
    column1.setColumnName("NewColumn1");

    // Тип поля указывается классами  из пакета com.borland.dx
// Тип данных в столбце
   column2.setDataType(com.borland.dx.dataset.Variant.STRING);  
    column2.setServerColumnName("NewColumn2");
    column2.setSqlType(0);
// Тип данных в столбце
   column3.setDataType(com.borland.dx.dataset.Variant.SHORT);
    column3.setServerColumnName("NewColumn3");
    column3.setSqlType(0);
// Тип данных в столбце
    column1.setDataType(com.borland.dx.dataset.Variant.SHORT);
    column1.setServerColumnName("NewColumn1");
    column1.setSqlType(0);
// Определение связи набора данных с текстовым файлом
    tableDataSet1.setDataFile(textDataFile1);  
    textDataFile1.setFileName("D:\J8\ImportText.txt");
    textDataFile1.setSeparator(",");  // Разделитель между 
                                                // полями
 contentPane = (JPanel) this.getContentPane();  // Текущая 
                        // панель для размещения компонентов
    contentPane.setLayout(borderLayout1);  // Определяем 
                                         // компоновку
    this.setSize(new Dimension(500, 400));
    this.setTitle("Чтение данных из текстового файла");
    tableDataSet1.setColumns(new Column[] {column1, 
                                        column2,  
                                        column3});
// Устанавливаем связь визуальной таблицы с набором данных
    jdbTable1.setDataSet(tableData Set1);	    
tableScrollPane1.setHorizontalScrollBarPolicy(
                JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
tableScrollPane1.setVerticalScrollBarPolicy(
                       JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    contentPane.add(tableScrollPane1, BorderLayout.CENTER);
    tableScrollPane1.getViewport().add(jdbTable1, null);
  }
protected void processWindowEvent(WindowEvent e) {
    super.processWindowEvent(e);
    if (e.getID() == WindowEvent.WINDOW_CLOSING) 
        {    System.exit(0);   // Завершение приложения
        }
}
}

Сохранение данных из открытого набора данных в текстовом файле выполняется методом Save.

Следующий пример иллюстрирует сохранение набора данных, выполняемое в обработчике события actionPerformed.

void button1_actionPerformed(ActionEvent e) {
  try {
      tableDataSet1.getDataFile().save(tableDataSet1);
      System.out.println ("Изменения успешно сохранены в файле");  }
  catch (Exception ex) 
{   
System.out.print("При сохранении файла произошла "); 
System.err.println(" ошибка: " + ex);           }
}

Использование JDBC-драйверов

Язык Java позволяет реализовывать доступ к таблице базы данных как через JDBC-драйверы, так и через мост JDBC-ODBC.

В любом случае для доступа к базе данных выполняется следующая последовательность действий:

  1. Загружается класс драйвера. Это можно выполнить двумя способами:
    • явно загрузить класс драйвера, регистрирующий себя в списке драйверов:
      // Параметр определяет применение моста JDBC-ODBC
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");	
      // Параметр определяет применение JDBC-драйвера для БД Oracle	
      DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
    • добавить имя драйвера в список системного свойства jdbc.drivers. Названия драйверов в списке разделяются символом двоеточия (например, jdbc.drivers=my.sql.Driver:wombat.sql.Driver;). При инициализации класс DriverManager просматривает системное свойство jdbc.drivers и в том случае, если пользователь добавил один или несколько драйверов, менеджер драйверов пытается их загрузить.
  2. Устанавливается соединение с базой данных. После загрузки драйвера можно использовать класс DriverManager для открытия соединения с источником данных:
    // Мост JDBC-ODBC указывается как jdbc:odbc,
    // а DSN - это имя ODBC источника данных
        Connection con = DriverManager.getConnection (
        "jdbc:odbc:DSN", "login", "password");
    // Подключение к БД Oracle для пользователя scott с паролем tiger
        Connection con = DriverManager.getConnection ( 
    "jdbc:oracle:oci:@datai_com", "scott", "tiger");

Загружать и регистрировать драйверы можно как методом Class.forName, так и методом DriverManager.registerDriver. Но в первом случае экземпляр драйвера создается неявно, а во втором при регистрации драйвера явным образом создается экземпляр драйвера.

При создании объекта типа Connection метод getConnection определяет параметр, содержащий JDBC-URL и передаваемый менеджером драйверов последовательно всем зарегистрированным драйверам: если драйвер распознает URL, то он возвращает экземпляр класса, реализующий интерфейс Connection. Этот экземпляр класса и возвращает менеджер драйверов в результате вызова метода getConnection.

Далее для извлечения данных из результирующего набора в переменные языка Java выполняются:

  1. Создание результирующего набора при выполнении SQL-оператора SELECT:
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT F1,F2,F3 FROM Table1");
  2. Выборка данных из результирующего набора:
    while (rs.next()) {
          int x = rs.getInt("F1");  // Имя поля F1
          String s = rs.getString("F2");
          float f = rs.getFloat("F3");
          }

Метод executeQuery используется для создания результирующего набора, а для выполнения SQL-оператора, изменяющего информацию в базе данных, вызывается метод executeUpdate.

После завершения работы с данными необходимо последовательно освободить результирующий набор, оператор и соединение.

Например:

rs.close();
stmt.close();
con.close();

Возвращать результирующий набор может не только выполнение оператора SELECT, но и выполнение хранимой процедуры. Вызов хранимых процедур определяется интерфейсом java.sql.CallableStatement.

Например:

import oracle.jdbc.driver.*;   // Для работы с JDBC-драйвером Oracle
import java.sql.*;
:
CallableStatement cstmt;   // Вызываемый операторный объект
cstmt= con.prepareCall("{packeg1.metod1(?)}") // Оператор вызова
                         // хранимой процедуры packeg1.metod1
cstmt.registerOutParameter(1,OracleTypes.CURSOR); // Регистрация
                         // выходного параметра
cstmt.execute(); // Выполнение операторного объекта
OracleResultSet ors= (OracleResultSet) 
((OracleCallableStatement) cstmt).getCursor(1);  // Получение  
                        // результирующего набора для БД Oracle
                    // из выходного параметра хранимой процедуры

По умолчанию при подключении через JDBC установлен режим автокоммита. Для применения транзакций этот режим следует отключить, а фиксацию изменений указывать явным вызовом метода Commit.

Например:

Connection con = DriverManager.getConnection ("jdbc:oracle:oci:@datai_com", "scott", "tiger");
con.setAutoCommit(false);
:
con.commit();   // Фиксация транзакции
:
con.rollback();   // Откат транзакции

Следующий пример иллюстрирует код приложения, выполняющего создание таблицы базы данных, доступ к которой выполняется через мост JDBC-ODBC.

import java.sql.*;   // Импорт пакета из JDK

public class CreateMyTable {
   public static void main(String args[]) {
   String url = "jdbc:odbc:myDataSource";    // myDataSource - 
                                   // имя источника данных DSN
   Connection con;
   String createString = "create table TEST (P1  VARCHAR(32)," 
                       +   	    " P2   INTEGER, " +
                              	    " P3   FLOAT, " +
                            	    " P4   INTEGER)" ;
   Statement stmt;
   try {
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");   // Загрузка драйвера

        } catch(java.lang.ClassNotFoundException e) {
        System.err.print("ClassNotFoundException: ");
        System.err.println(e.getMessage());
        }
   try {
// Соединение с источником данных с использованием объекта типа Connection
   con = DriverManager.getConnection(url, "Login", "Psw");
   stmt = con.createStatement();   // Создание объекта оператор класса Statement
   stmt.executeUpdate(createString);   // Выполнение SQL-оператора
   stmt.close();   // Освобождение объекта "оператор"
   con.close();    // Закрытие соединения
      } catch(SQLException ex) {
      System.err.println("SQLException: " + ex.getMessage());
        }
    }
}

Компоненты DATABASE и QUERYDATASET

Для доступа к таблицам базы данных можно использовать компоненты палитры инструментов окна дизайнера среды JBuilder, которые предоставляют разработчику значительно более удобный графический интерфейс. Наиболее простой способ отображения набора данных - это использование компонента JdbTable.

Для того чтобы самым простым способом отобразить значения из таблицы базы данных, следует добавить в проект в окне дизайнера компонент Database и определить для него значение свойства connection, указав используемый драйвер и путь доступа к базе данных или к DSN-источнику данных. При двойном щелчке мышью на свойстве connection JBUILDER откроет диалог Connection (рис. 13.1). Список Driver содержит все доступные приложению JDBC-драйверы.

Диалог определения свойства Connection компонента Database
Рис. 13.1.  Диалог определения свойства Connection компонента Database

Для автоматического отсоединения от базы данных при завершении приложения добавьте в окно компонент dbDisposeMonitor со страницы More dbSwing и установите значение его свойства dataAwareComponent равным this (компонент, при завершении которого будут закрываться все созданные для него соединения с базой данных).

Набор данных может быть указан компонентами TableDataSet и QueryDataSet.

Выполняемый для формирования набора данных SQL-оператор определяется в компоненте QueryDataSet. Этот компонент следует добавить в окно и двойным щелчком мыши на свойстве query открыть диалог определения запроса (рис. 13.2). В нем выбрать используемый объект типа Database и вручную или посредством построителя запросов SQL Builder (рис. 13.3) сформировать код SQL-оператора.

Редактор свойства query компонента QueryDataSet
Рис. 13.2.  Редактор свойства query компонента QueryDataSet

Диалог SQL Builder для формирования SQL-оператора
Рис. 13.3.  Диалог SQL Builder для формирования SQL-оператора

Выбрав вкладку SQL, в любой момент времени можно просмотреть, как формируется SQL-оператор.

Для визуального отображения данных удобнее всего использовать компонент JdbTable со страницы dbSwing палитры компонентов. Этот компонент следует размещать в контейнере, реализуемом компонентом TableScrollPane.

Связь визуального компонента JdbTable, связь с набором данных определяется значением свойства dataset, выбираемым из предлагаемого списка.

Для того чтобы сохранить в таблице базы данных сделанные пользователем изменения, можно воспользоваться одним из следующих способов:

  • расположить в окне компонент JdbNavToolBar и связать его с набором данных, установив значение свойства dataset;
  • расположить в окне командную кнопку и добавить для нее блок прослушивания для события действия. В созданный метод обработки события button_actionPerformed ввести следующий код:
    try {   database1.saveChanges(queryDataSet1);  }
    catch (Exception ex) {;}

Параметризированные запросы

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

Для создания параметризированных запросов используется компонент ParameterRow.

Двойным щелчком на компоненте ParameterRow в окне структуры следует открыть редактор столбцов и добавить по одному столбцу на каждый параметр. Значение свойства columnName будет использоваться во фразе where SQL-оператора.

Например: select * from tbl1 where ind1<= :column1 Таким образом, компонент ParameterRow связывается с набором данных.

Для связывания компонента с набором данных используется или вкладка Where диалога SQL Builder (предварительно указывается используемый компонент ParameterRow на вкладке Parameters диалога Query), или вкладка SQL, на которой выполняется непосредственный ввод фразы WHERE SQL-оператора SELECT.

Компонент DATASTORE

Компонент DataStore представляет JDS-файл базы данных DataStore.

JBuilder предоставляет набор классов, поддерживающих работу с базой данных DataStore. Основные из них расположены на станице DataExpress палитры компонентов окна дизайнера.

Для того чтобы создать файл базы данных DataStore, надо выполнить следующие действия:

  1. Создать объект типа DataStore.
    DataStore my_store = new DataStore();
  2. Определить имя создаваемой базы данных:
     my_store.setFileName("BD_DSTORE.jds");
  3. Определить имя пользователя, имеющего доступ к создаваемой базе данных:
    my_store.setUserName("CreateTx");
  4. Назначить используемый менеджер транзакций:
    my_store.setTxManager(new TxManager());
  5. Cоздать файл базы данных:
    store.create();

Для открытия и закрытия базы данных используются методы open и close объекта типа DataStore. Следующий пример иллюстрирует открытие базы данных типа DataStore.

import com.borland.datastore.*;
public class CreateNew_DataStore
{
  public static void main(String[] args)
  {    DataStore ds1 = new DataStore();
    try   
  { ds1.setFileName("DS1.jds");  // Определяем имя БД
     java.io.File f = new   java.io.File(ds1.getFileName());
                  ds1.setUserName("CreateTx");
                  ds1.setTxManager(new TxManager());
 if(!f.exists()) ds1.create();  // Создание БД
 else              ds1.open();      
                    ds1.close();    }
    catch(Exception ex)    {      System.out.println(ex);    }
  }
}       

Открыть базу данных DataStore можно несколькими способами:

  • выполнить метод open класса DataStore;
  • использовать класс DataStoreConnection;
  • выполнить метод getConnection класса DriverManager.

Механизм доступа к базе данных DataStore через JDBC-драйверы не отличается от механизма доступа к любой другой базе данных. В качестве загружаемого драйвера можно использовать com.borland.datastore.jdbc.DataStoreDriver.

Например: Class.forName("com.borland.datastore.jdbc.DataStoreDriver");

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

Адрес ПК указывается следующим образом:

  • для локального компьютера - "jdbc:borland:dslocal:";
  • для удаленного компьютера - "jdbc:borland:dsremote://localhost/"

Например:

Connection con = DriverManager.getConnection(URL + FILE, "user", "")

Классы и интерфейсы, применяемые для работы с базами данных

Класс DRIVERMANAGER

Класс DriverManager предоставляет средства для управления JDBC драйверами и реализует следующие методы:

  • static Connection getConnection (String url) - метод, устанавливающий соединение с базой данных, указанной параметром url;
  • static Connection getConnection (String url, String user, String password) - метод, устанавливающий соединение с базой данных, указанной параметром url; параметры user и password определяют имя и пароль пользователя;
  • static int getLoginTimeout () - метод, определяющий максимальный интервал ожидания (в секундах) соединения с базой данных;
  • static void setLoginTimeout (int seconds) - метод, устанавливающий максимальный интервал ожидания (в секундах) соединения с базой данных;
  • static void registerDriver (Driver driver) - метод, выполняющий регистрацию заданного драйвера в списке драйверов менеджера драйверов;
  • static void deregisterDriver (Driver driver) - метод, удаляющий драйвер из списка менеджера драйверов.

Интерфейс CONNECTION

Интерфейс java.sql.Connection определяет основные возможности для соединения с базой данных и предоставляет следующие константы и методы:

  • static final int TRANSACTION_NONE - константа, определяющая отсутствие поддержки транзакций;
  • static final int TRANSACTION_READ_UNCOMMITTED - константа, определяющая режим "чтение без фиксации". Этот уровень изоляции позволяет читать из транзакции строки, измененные в другой незавершенной транзакции;
  • static final int TRANSACTION_READ_COMMITTED - константа, определяющая режим "чтение с фиксацией". Данный режим предотвращает возможность "грязного" чтения (dirty read), но допускает неоднократное выполнение одного и того же запроса с различными результатами (неповторяющееся чтение) и фантомное чтение;
  • static int TRANSACTION_REPEATABLE_READ - константа, определяющая режим повторяющегося чтения, который предотвращает возможность "грязного" чтения (dirty read) и неповторяющегося чтения, но допускает фантомное чтение;
  • static int TRANSACTION_SERIALIZABLE - константа, определяющая режим "последовательное выполнение", который предотвращает возможность "грязного" чтения, неповторяющегося чтения и фантомного чтения;
  • void close () - метод, закрывающий соединение с базой данных и освобождающий JDBC ресурсы;
  • void commit () - метод, фиксирующий сделанные изменения в базе данных;
  • Statement createStatement () - метод, создающий объект Statement, используемый для передачи SQL-оператора базе данных;
  • Statement createStatement(int resultSetType, int resultSetConcurrency) - метод, создающий объект Statement, который будет создавать объект ResultSet указанного типа и с заданным уровнем параллельности. Параметр resultSetType определяется как ResultSet.TYPE_XXX, а параметр resultSetConcurrency - как ResultSet.CONCUR_XXX;
  • boolean getAutoCommit () - метод, определяющий, установлен ли режим автокоммита;
  • DatabaseMetaData getMetaData () - метод, возвращающий объект DatabaseMetaData, содержащий метаданные для подсоединенной базы данных;
  • int getTransactionIsolation () - метод, возвращающий установленный уровень изоляции;
  • boolean isClosed () - метод, определяющий, закрыто ли соединение;
  • booleanisReadOnly () - метод, определяющий, установлен ли для соединения режим "только чтение";
  • CallableStatement prepare Call(String sql) - метод, создающий объект CallableStatement, используемый для вызова хранимых процедур;
  • CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) метод, создающий объект CallableStatement, который будет создавать объект ResultSet заданного типа и с указанным уровнем параллельности;
  • PreparedStatement prepareStatement (String sql) - метод, создающий объект PreparedStatement, используемый для выполнения параметризированного SQL-оператора;
  • void rollback () - метод, выполняющий откат транзакции;
  • void setAutoCommit(boolean autoCommit) - метод, включающий или отключающий режим автокоммита;
  • void setReadOnly (boolean readOnly) - метод, включающий или отключающий режим "только чтение";
  • void setTransactionIsolation (int level) - метод, устанавливающий заданный уровень изоляции.

Интерфейс STATEMENT

Интерфейс java.sql.Statement реализует средства, позволяющие выполнять SQL-операторы, и предоставляет следующие методы:

  • boolean execute (String sql) - метод, выполняющий SQL-оператор, при котором может быть возвращено несколько результирующих наборов;
  • int[] executeBatch () - метод, позволяющий выполнить набор SQL-операторов;
  • ResultSet executeQuery (String sql) - метод, выполняющий SQL-оператор, который возвращает один объект типа ResultSet;
  • int executeUpdate (String sql) - метод, выполняющий SQL-оператор, который не возвращает результирующего набора (INSERT, UPDATE или DELETE);
  • Connection getConnection () - метод, возвращающий объект Connection, который использован для данного объекта типа Statement;
  • Boolean getMoreResults () - метод, выполняющий перемещение на следующий результирующий набор в объекте Statement.

Интерфейс RESULTSET

Интерфейс java.sql.ResultSet реализует средства для работы с результирующим набором и предоставляет следующие константы и методы:

  • static int CONCUR_READ_ONLY - константа, определяющая режим результирующего набора "только чтение";
  • static int CONCUR_UPDATABLE - константа, определяющая, что результирующий набор может быть изменяемым;
  • static int FETCH_FORWARD - константа, определяющая, что строки в результирующем наборе обрабатываются только в одном направлении: от первой к последней;
  • static int FETCH_REVERSE - константа, определяющая, что строки в результирующем наборе обрабатываются только в одном обратном направлении: от последней к первой. Эта константа используется в методе setFetchDirection как подсказка драйверу, которую тот может и игнорировать.
  • static int FETCH_UNKNOWN - константа, указывающая, что порядок, в котором будут обрабатываться строки результирующего набора, не определен;
  • static int TYPE_FORWARD_ONLY - константа, определяющая режим, при котором позиция курсора может перемещаться только в направлении вперед;
  • static int TYPE_SCROLL_INSENSITIVE - константа, определяющая режим, при котором позиция курсора может изменяться в любом направлении, но результирующий набор нечувствителен к изменениям, вносимым другими транзакциями;
  • static int TYPE_SCROLL_SENSITIVE - константа, определяющая режим, при котором позиция курсора может изменяться в любом направлении и результирующий набор чувствителен к изменениям, вносимым другими транзакциями;
  • boolean absolute (int row) - метод, выполняющий перемещение позиции курсора результирующего набора на указанную строку;
  • void afterLast () - метод, устанавливающий позицию курсора в конец результирующего набора после последней строки;
  • void beforeFirst () - метод, устанавливающий позицию курсора в начало результирующего набора перед первой строкой;
  • void cancelRowUpdates () - метод, отменяющий изменения, сделанные в текущей строке результирующего набора;
  • void clearWarnings () - метод, удаляющий все уведомляющие сообщения, полученные для результирующего набора;
  • void close () - метод, закрывающий результирующий набор и освобождающий все JDBC-ресурсы;
  • void deleteRow () - метод, удаляющий текущую строку из результирующего набора и из источника данных;
  • int findColumn (String columnName) - метод, возвращающий индекс столбца результирующего набора по заданному имени;
  • boolean first () - метод, перемещающий позицию курсора на первую строку результирующего набора;
  • Array getArray (int i) и Array getArray (String colName) - методы, возвращающие значение указанного столбца в виде массива (столбец может быть указан по имени или по индексу);
  • BigDecimal getBigDecimal (int columnIndex) и BigDecimal getBigDecimal (String columnName) - методы, возвращающие значение указанного столбца как объект типа java.math.BigDecimal;
  • Blob getBlob (int i) и Blob getBlob (String colName) - методы, возвращающие значение указанного столбца как Blob-объект;
  • boolean getBoolean (int columnIndex) и boolean getBoolean (String columnName) - методы, возвращающие значение указанного столбца как логическое значение;
  • byte getByte (int columnIndex) и byte getByte (String columnName) - методы, возвращающие значение указанного столбца как байт;
  • byte[] getBytes (int columnIndex) и byte[] getBytes (String columnName) - методы, возвращающие значение указанного столбца как массив байтов;
  • Clob getClob (int i) и Clob getClob (String colName) - методы, возвращающие значение указанного столбца как Сlob-объект;
  • int getConcurrency () - метод, возвращающий установленный режим параллельности, который определяется значением CONCUR_READ_ONLY или CONCUR_UPDATABLE;
  • String getCursorName() - метод, возвращающий имя курсора, используемое объектом ResultSet;
  • Date getDate(int columnIndex), Date getDate(String columnName), Date getDate(int columnIndex, Calendar cal) и Date getDate(String columnName, Calendar cal) - методы, возвращающие значение указанного столбца как объект типа java.sql.Date;
  • double getDouble (int columnIndex) и double getDouble (String columnName) - методы, возвращающие значение указанного столбца как значение типа double;
  • int getFetchDirection() - метод, возвращающий используемое направление выборки данных из результирующего набора;
  • int getFetchSize() - метод, возвращающий для объекта ResultSet размер текущей выборки данных;
  • float getFloat(int columnIndex) и float getFloat(String columnName) - методы, возвращающие значение указанного столбца как значение типа float;
  • int getInt(int columnIndex) и int getInt(String columnName) - методы, возвращающие значение указанного столбца как значение типа int;
  • long getLong(int columnIndex) и long getLong(String columnName) - методы, возвращающие значение указанного столбца как значение типа long;
  • ResultSetMetaData getMetaData() - метод, возвращающий в объекте ResultSetMetaData информацию о количестве, типе и свойствах столбцов результирующего набора;
  • int getRow() - метод, возвращающий номер текущей строки;
  • short getShort(int columnIndex) и short getShort(String columnName) - методы, возвращающие значение указанного столбца как значение типа short;
  • Statement getStatement() - метод, возвращающий объект Statement, который был использован для создания данного результирующего набора;
  • String getString(int columnIndex) и String getString(String columnName) - методы, возвращающие значение указанного столбца как значение типа String;
  • Time getTime (int columnIndex), Time getTime (String columnName), Time getTime (int columnIndex, Calendar cal) и Time getTime (String columnName, Calendar cal) - методы, возвращающие значение указанного столбца как значение типа java.sql.Time;
  • Timestamp getTimestamp (int columnIndex), Timestamp getTimestamp (String columnName), Timestamp getTimestamp (int columnIndex, Calendar cal) и Timestamp getTimestamp (String columnName, Calendar cal) - методы, возвращающие значение указанного столбца как значение типа java.sql.Timestamp;
  • int getType () - метод, возвращающий тип данного результирующего набора;
  • SQLWarning getWarnings () - метод, возвращающий первое уведомляющее сообщение, которое было получено для результирующего набора;
  • void insertRow () - метод, вставляющий строку, которая была сформирована как новая строка в специальной области результирующего набора, в результирующий набор и в источник данных;
  • boolean isAfterLast () - метод, определяющий, находится ли позиция курсора после последней строки результирующего набора;
  • boolean isBeforeFirst () - метод, определяющий, находится ли позиция курсора перед первой строкой результирующего набора;
  • boolean isFirst () - метод, определяющий, находится ли позиция курсора на первой строке результирующего набора;
  • boolean isLast () - метод, определяющий, находится ли позиция курсора на последней строке результирующего набора;
  • boolean last () - метод, перемещающий позицию курсора на последнюю строку результирующего набора;
  • void moveToCurrentRow () - метод, возвращающий позицию курсора на текущую строку;
  • void moveToInsertRow () - метод, перемещающий позицию курсора на вставляемую строку;
  • boolean next () - метод, перемещающий позицию курсора на следующую строку результирующего набора;
  • boolean previous () - метод, перемещающий позицию курсора на предыдущую строку результирующего набора;
  • void refreshRow () - метод, выполняющий обновление значений текущей строки значениями из базы данных;
  • void updateRow () - метод, выполняющий внесение изменений значений текущей строки в базу данных;
  • boolean relative(int rows) - метод, перемещающий позицию курсора на указанное количество строк (когда такое перемещение разрешено) вперед, если параметр rows - больше нуля, или назад, если значение rows отрицательное;
  • boolean rowDeleted () - метод, определяющий, была ли строка удалена;
  • boolean rowInserted () - метод, определяющий, была ли текущая строка вставлена;
  • boolean rowUpdated () - метод, определяющий, была ли текущая строка изменена;
  • void setFetchDirection(int direction) - метод, устанавливающий направление обработки строк результирующего набора;
  • void setFetchSize(int rows) - метод, предлагающий JDBCдрайверу ограничить количество строк, выбираемых в результирующий набор из базы данных;
  • boolean wasNull() - метод, определяющий, имел ли последний прочитанный столбец значение SQL NULL;
  • void updateNull(int columnIndex) и void updateNull(String columnName) - методы, устанавливающие значение указанного столбца как null;
  • void updateBigDecimal(int columnIndex, BigDecimal x), void updateBigDecimal(String columnName, BigDecimal x), voidupdateBoolean(int columnIndex, boolean x), void updateBoolean(String columnName, boolean x), void updateBoolean(String columnName, boolean x), void updateByte(int columnIndex, byte x), void updateByte(String columnName, byte x), void updateBytes(int columnIndex, byte[] x), void updateBytes(String columnName, byte[] x), void updateDate(int columnIndex, Date x), void updateDate(String columnName, Date x), void updateDouble(int columnIndex, double x), void updateDouble(String columnName, double x), void updateFloat(int columnIndex, float x), void updateFloat(String columnName, float x), void updateInt(int columnIndex, int x), void updateInt(String columnName, int x), void updateLong(int columnIndex, long x), void updateLong(String columnName, long x), void updateObject(int columnIndex, Object x), void updateObject(int columnIndex, Object x, int scale), void updateObject(String columnName, Object x), void updateObject(String columnName, Object x, int scale), void updateShort(int columnIndex, short x), void updateShort(String columnName, short x), void updateString(int columnIndex, String x), void updateString(String columnName, String x), void updateTime(int columnIndex, Time x), void updateTime(String columnName, Time x), void updateTimestamp(int columnIndex, Timestamp x), void updateTimestamp(String columnName, Timestamp x) - методы, используемые для изменения значений столбцов в соответствии с их типами.

Реализация доступа к базам данных в среде ORACLE JDEVELOPER

Среда проектирования

Среда проектирования Oracle JDeveloper позволяет создавать приложения различных типов на языке Java, включая создание сервлетов, JSP-страниц, клиентских Java-приложений, аплетов, компонентов JavaBeans, компонентов EJB, построение XML-приложений Oracle, формирование хранимых процедур, генерацию форм данных InfoBus, разработку компонентов с архитектурой Business Component for Java (BC4J). Для реализации доступа к базам данных среда JDeveloper позволяет применять как механизм JDBC, так и создавать специальные SQLJ-приложения.

Разработка любого приложения начинается с создания рабочего пространства (команда меню File | New Workspace)., Затем создания проекта (команда меню File | New Project), при котором в зависимости от выбранного типа проекта мастером построения проекта формируется пустой проект или проект указанного типа.

Построение SQLJ-приложений

Для создания SQLJ-приложения следует сформировать пустой проект, а затем добавить в него SQLJ-файл (команда меню File | New, выбрать пиктограмму SQLJFile).

SQLJ-файл - это файл с кодом программы на языке Java, в который включены SQLJ-операторы.

SQLJ-операторы могут быть двух видов:

  • SQLJ-объявления;
  • SQLJ-исполняемые операторы.

SQLJ-оператор может иметь следующее формальное описание:

#sql {sql-оператор };  // Оператор без возвращения результирующего набора

или

#sql выражение={sql-оператор};          // Оператор, возвращающий 
                                        // результирующий набор

Для поддержки возможности подключения во время компиляции SQLJ-транслятора к базе данных, с целью проверки синтаксиса введенного SQL-кода, следует создать объект соединение (команда меню Project | Properties, вкладка SQLJ), установить флажок Check SQL semantics against database shcema, выбрать New Connection и определить параметры подключения к базе данных, введя ее URL-адрес (localhost на локальном компьютере), имя пользователя и пароль).

При формировании SQLJ-приложения среда JDeveloper автоматически вставляет в начало приложения код, выполняющий подключение необходимых библиотек.

Например:

import sqlj.runtime.*;
import sqlj.runtime.ref.*;
import java.sql.*;
import java.sql.Date;
import oracle.sql.*;
import oracle.sqlj.runtime.Oracle;
public class MySQLJ1 { 
public MySQLJ1() {}  // Конструктор
public static void main (String[] args) throws SQLException { }
 }

Для подключения к базе данных из SQLJ-приложения первоначально следует создать объект типа данного класса, зарегистрировать драйвер и установить контекст по умолчанию.

Например:

MySQLJ1 sqlapp= new MySQLJ1();
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
DefaultContext.setDefaultContext( new DefaultContext(
       "jdbc:oracle:thin:@db.com:1521:ORCL","scott","tiger",false));
if (DefaultContext.getDefaultContext==null){
// Ошибка подключения к базе данных)
}

Для доступа к таблице базы данных следует объявить класс итератора (вставить в код класса до метода main).

Например:

#sql public iterator Tbl1Iter (int f1, string f2, float f3);

Итераторы могут быть именованные и позиционные. SQLJ-транслятор в зависимости от типа итератора генерирует класс итератора, реализующий интерфейс sqlj.runtime.NamedIterator или sqlj.runtime.PositionedIterator. Оба этих интерфейса наследуют интерфейс ResultSetIterator, предоставляющий следующие методы:

  • getResultSet - извлечение из итератора результирующего набора;
  • next - переход к следующей строке итератора;
  • isClosed - определение, закрыт ли итератор;
  • close - закрытие итератора.

Для использования итератора следует объявить объект типа итератора, описать выполняемый итератор, а затем, используя метод next, последовательно выбирать строки результирующего набора.

Например:

Tbl1Iter t1=null;   // Объект типа итератора
#sql t1= { SELECT       //Выполняемый итератор
             Fl1 as a1, Fl2 as a2, Fl3 as a3
             FROM Tbl1};
while (t1.next()){
System.out.println( t1.a1());  // Вывод значения столбца
                               // результирующего набора
System.out.println( t1.a2());  
System.out.println( t1.a3()); 
}
t1.close();      // Закрытие итератора