Название: Java и базы данных - Методические указания (В.Н. Глазков)

Жанр: Информатика

Просмотров: 1489


Подготовленные инструкции

 

Подготовленная инструкция – та, которая посылается базе данных до её выполнения. В отличие от хранимых процедур, подготовленные инструкции не остаются в базе данных после того, как освобождаются связанные с ними ресурсы. Эти инструкции могут вызываться несколько раз с различными значениями параметров. При выполнении подготовленной инструкции она уже находится в базе данных. Передаются только значения параметров IN.

Работа с подготовленными инструкциями включает в себя следующие этапы:

· подготовка инструкции SQL,

· задание параметров IN,

· выполнение инструкции,

· получение результатов (если они есть),

· задание новых значений параметров IN,

и выполнение инструкции ещё раз.

Для получения объекта PreparedStatement используется (интерфейс) класс Connection: PreparedStatement repare Statement (String sql); Параметры обозначаются символами "?". Параметры IN подготовленной инструкции задаются так же, как и для вызываемых инструкций методами setXXX() интерфейса PreparedStatement.

Подготовленная инструкция может возвращать как числовое

значение, так и объект ResultSet.

//...

String url = "jdbc:odbc.mySource";

String uid = "javauser";   

String pwd = "hotjava";

Connectionc cnct = // создание объекта Connection

DriverManager.getConnection(url, uid, pwd);

PreparedStatement myStmt = cnct.PrepareStatement(

"Update kadr SET podr = ? WHERE name = ?");

myStmt.setInt(1, 5);          

myStmt.String(2, "Ivanov");

int res = myStmt.executeUpdate();

myStmt.close();

cnct.close(); //...

 

Вставка/извлечение больших двоичных объектов

из БД

 

В языке SQL не предусмотрена работа с большими двоичными объектами – Blob (BLOB – Binary Large Object), но JDBC содержит необходимые методы для вставки и извлечения Blob из базы  данных.

В автономных приложениях Java возможно использование мультимедийных средств, также как в Java-апплетах и в Web-документах. Потоки Java можно применять для пересылки/получения больших двоичных объектов: рисунков, аудиофайлов, двоичных данных. Рекомендуется пересылать двоичные данные порциями фиксированного размера, используя потоки ввода/вывода. Получение потоков поддерживается тремя различными методами задания параметров IN:

 

getBinaryStream() – не выполняет никаких преобразований,

getAsciiStream() – возвращает поток Ascii-символов длиной в

             один байт,

getUnicodeStream() – возвращает поток Unicode-символов длиной

                    в два байта.

 

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

 

Примеры обновления/получения больших

двоичных объектов базы данных

 

// Обновление записей базы данных - вставка больших двоичных

// файлов с заданием IN и OUT параметров  в командной строке.

// Пример БД ( имя blob.mdb, псевдоним blob) с таблицей blob:

//

// Text  Поле объекта OLE       <--типы полей для Access

// name    pict                 <--имена полей

// vova  Точечный рисунок bmp   <--содержание полей

// vera  Точечный рисунок bmp   <--содержание полей

 

import java.sql.*;

import java.io.*;

import java.util.*;

class txblob

{ static String url = "jdbc:odbc:blob";

static String driver = "sun.jdbc.odbc.JdbcOdbcDriver";

static String uid = "javauser";

static String pwd = "hotjava";

static String tablename = "";

static String blobcolumnname = "";

static String selectcolumnname = "";

static String selectcolumnvalue = "";

static Connection cnct = null;

static String filename=""; 

 

public static void main (String argv[]) throws IOException { 

    if(argv[0].equals("-c")) { // "-c" означает, что ожидаются

                     // параметры в командной строке

tablename = argv[1] ;  

blobcolumnname = argv[2] ;    // бинарное поле

selectcolumnname = argv[3] ;  // имя выбранного поля

selectcolumnvalue = argv[4] ; // значение выбранного поля

filename =argv[5];   // имя файла, из которого берём blob

txblob session = new txblob();// создание объекта этого класса

// командная строка: >java txblob -c blob pict name vova 

                 vova.bmp                                   

// vova.bmp – файл, из которого берётся рисунок

}

}

public txblob() throws IOException    {

  try  {

         Class.forName(driver);

         cnct = DriverManager.getConnection(url, uid, pwd);

         }   

catch(java.lang.Exception ex) {ex.printStackTrace(); return;}

      

processBlob();

finalize();

}

protected void  finalize(){ //закрытие соединения

  try {  cnct.close();}

  catch(java.sql.SQLException ex)

{  ex.printStackTrace();  }       

  }

 

protected void  processBlob() throws IOException {

   try{  java.io.File blobFile = new java.io.File(filename);

     // размер blob-объекта

     int blobFileLen = (int) blobFile.length();

     //вх. поток из blob-источника

     java.io.InputStream fblob = new 

     java.io.FileInputStream(blobFile);

     // подготовка инструкции для обновления поля:

     PreparedStatement myStmt = cnct.prepareStatement(

     "UPDATE  " + tablename + " SET " + blobcolumnname

     +" = " +"?  WHERE " + selectcolumnname + " = ?");

     //

      myStmt.setBinaryStream(1, fblob, blobFileLen);

      myStmt.setString(2, selectcolumnvalue);

      //выполнение обновления

      int res = myStmt.executeUpdate();

          myStmt.close();

}

  catch(java.sql.SQLException ex) { System.out.println(ex); }   

  catch(java.lang.Exception ex)   { ex.printStackTrace();   }   

}

}

Получение из базы данных больших двоичных файлов

 

//  Text  Поле объекта OLE    

//  name    pict              

//  vova  Точечный рисунок bmp

//  vera  Точечный рисунок bmp

 

import java.sql.*;

import java.io.*;

import java.util.*;

class rxblob

 

{ static String url = "jdbc:odbc:blob";

static String driver = "sun.jdbc.odbc.JdbcOdbcDriver";

static String uid = "javauser";

static String pwd = "hotjava";

static String tablename = "";

static String blobcolumnname = "";

static String selectcolumnname = "";

static String selectcolumnvalue = "";

static Connection cnct = null;

static String filename="";

 

public static void main (String argv[]) throws IOException

{

 

if(argv[0].equals("-c")) {

tablename = argv[1] ;  

blobcolumnname = argv[2] ;

selectcolumnname = argv[3] ;

selectcolumnvalue = argv[4] ;

filename =argv[5];

// командная строка: >java rxblob -c blob pict name vova

               vov.bmp

// vov.bmp создаётся под рисунок

      rxblob session = new rxblob();

  }

}

public rxblob() throws IOException

{

  try       {   Class.forName(driver);

      cnct = DriverManager.getConnection(url, uid, pwd);

   }   

   catch(java.lang.Exception ex)

  {

         ex.printStackTrace(); return;

        }

       

       processBlob();

       finalize();

    }

protected void  finalize(){

      try {  cnct.close();}

      catch(java.sql.SQLException ex)

      {

       ex.printStackTrace();

       }       

     }

 

protected void  processBlob() throws IOException

{

  try{

       java.io.File blobFile = new java.io.File(filename);

       java.io.OutputStream fblob = new

                       java.io.FileOutputStream(blobFile);

       java.sql.Statement  myStmt = cnct.createStatement();

       checkWarnings(myStmt.getWarnings());

       ResultSet rs = myStmt.executeQuery( "SELECT   " +

       blobcolumnname +  "  FROM  " +  tablename + " WHERE  " 

       +  selectcolumnname +" = " + selectcolumnvalue);

       checkWarnings(rs.getWarnings());

       // создаём буфер в 4 к

                byte[] buffer = new byte[4096];

                int size;

                if(rs.next()) // выбираем blob

                {   java.io.InputStream in =

                        rs.getBinaryStream( blobcolumnname );

                for(;;)        {

     size = in.read(buffer);

     System.out.println("size = "+size);

     if(size==0) break;

     fblob.write(buffer,0,size);

        }

      }

else System.out.println("Not found");

myStmt.close();   cnct.close();

rs.close();

   }

catch(java.sql.SQLException ex)

{

System.out.println("in processBlob(): "+ex);

}   

 

catch(java.lang.Exception ex)

{

ex.printStackTrace();

}   

 }

}

 

Инструкции языка запросов SQL

 

Язык Java может работать с рядом инструкций из языка запросов SQL (Structured Query Language). Он хорошо известен многим пользователям и считается стандартом. Рассматриваемые ниже инструкции являются полезным и быстрым инструментом обработки данных. Инструкции SQL могут непосредственно включаться в программы в строковом виде наряду с собственными инструкциями Java.

Формирование запросов к базе данных. С помощью инструкции-запроса из базы-источника выделяются нужные данные и пересылаются на экран или в принимающую программу. Данные могут быть извлечены из разных таблиц базы данных, а также сгруппированы и упорядочены желаемым образом. Инструкция имеет массу опций-возможностей. Приведём её синтаксис для лучшего осознания деталей:

 

SELECT <что выводится>

  FROM <откуда(источник)>INTO <куда(получатель)>

  WHERE <каким условиям должно отвечать>

  GROUP BY <колонки, по которым выполняется группирование>

  HAVING <условие группирования записей в одну строку>

  ORDER BY <в каком порядке выводить данные>

 

Инструкции SELECT сами открывают нужные им базы данных.

SELECT [predicate] { * | table.* | [table.]field1 [AS alias1] [, [table.]field2 [AS alias2] [, ...]]}

FROM tableexpression [, ...] [IN externaldatabase]

[WHERE... ]

[GROUP BY... ]

[HAVING... ]

[ORDER BY... ]

[WITH OWNERACCESS OPTION]

 

Здесь «колонка» может быть и выражением.     Инструкция SELECT допускает включение в себя других внутренних инструкций SELECT (формирование подзапросов). <Выражение> может быть полем записи из БД, константой, выводимой в каждой строке выборки, функцией от переменных, полей и т.д. Если выражение является именем поля, то оно может включать имя базы данных или псевдонима, в особенности, если выборка делается из разных таблиц, где имена полей могут совпадать. Если необходимо построить выборку из всех полей базы данных, вместо их перечня можно указать символ "*".

В результате  выполненной выборки получается совокупность

колонок, заголовками которых могут быть имена полей.

В выражении могут использоваться любые методы Java и собственные специальные функции, действующие по «вертикали». Это функции вычисления среднего, минимального и максимального значений, суммирования, а также количества записей: AVG(<выр>), MIN(<выр>), MAX(<выр>), SUM(<выр>), COUNT(<выр>). В последней функции в качестве аргумента может быть звёздочка COUNT(<*>), что означает подсчёт всех записей, попавших в выборку. В качестве объекта-получателя, куда пересылается информация, могут быть: БД, массив, текстовый файл, экран и принтер. Информация может быть передана и в так называемый Курсор. Курсор – это временный набор данных, который может быть областью памяти или временным файлом только для чтения. Курсор может быть обработан другой командой SELECT.

Создание баз данных:

 

CREATE TABLE table (field1 type [(size)] [NOT NULL] [index1] [, field2 type [(size)] [NOT NULL] [index2] [, ...]] [, CONSTRAINT multifieldindex [, ...]])

 

Дополнение базы данных (вставка записей в БД):

 

INSERT INTO target [IN externaldatabase] [(field1[, field2[, ...]])]

SELECT [source.]field1[, field2[, ...]

FROM tableexpression

 

Запрос на добавление одной записи:

 

INSERT INTO target [(field1[, field2[, ...]])]

VALUES (value1[, value2[, ...])

 

Обновление базы данных:

UPDATE table  SET newvalue  WHERE criteria;

 

Удаление  в базе данных:

 

DELETE [table.*] FROM table WHERE criteria

 

Конфигурирование базы данных

 

Чтобы разработанный код приложения на Java заработал на

конкретной платформе (наша платформа: OC Windows 2000), необходимо предварительно загрузить драйвер JDBC и установить базу данных с помощью соответствующей программы-администратора баз данных.

Присоединять будем уже созданную в Microsoft Access 2000

базу данных с именем MyDB и с таблицей Table1 внутри, путь до которой: D:UsersPVBJavaDBBDMyDB.mdb.

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

· Нажимаем на иконку Мой компьютер.

Открываем Панель управления (Control panel). Там есть значок с именем ODBC Data Sources(32 bit) и описанием: Maintaims 32 bit ODBC data sources and drivers.

· Нажимаем на значке ODBC и попадаем на панель ODBC Data Source

Administrator. Здесь видим несколько закладок, включая

Пользовательский DSN ( User DSN) – по умолчанию эта панель, Системный DSN (System DSN), и т. д., где DSN обозначает имя  источника данных. Если надо проверять свою конфигурацию и создавать запросы, то необходимо также установить и Файловый DSN (File DSN). Это позволит инструменту Microsoft Query, который поставляется вместе с пакетом Microsoft Office, найти базу данных.

· На панели User DSN видим имена (как правило это псевдонимы – вторые короткие имена) и соответствующие им драйверы уже установленных источников данных. Стандарт ODBC поддерживает несколько различных форматов файлов разных СУБД.

· В разделе Системный DSN (System DSN) нажимаем кнопку Добавить (Add...) и попадаем в окно Create New Data, где в поле с предложением Select a driver for which you want to set up a date source:

· выбираем драйвер по имени, версии, компании (Name, Version, Company с File и Data), а именно: Microsoft Access Driver [*.mdb].

· Нажимаем кнопку Готово. После чего попадаем в следующее диалоговое окно:

ODBC Microsoft Access SetUp.  Здесь с помощью кнопки Select

· укажем директорию, в которой находится нами созданная база данных MyDB.mdb и саму базу данных. База данных чаще содержит не одну таблицу, а несколько, связанных между собой соединениями.

· Нажатие кнопки Select...  приводит к появлению окна Select

Database, где можно выбрать диск (в Drives:) c: или  d:...,

директорию на диске (в Directories:), тип файла (в List Files of Type: Access Datebases [*.mdb] или All Files[*.*]), и имя БД (в Datebase Name). Есть возможность подключить сетевой диск через кнопку Network...(эта ситуация здесь не рассматривается).

· Нажимаем кнопку OK.

· Возвращаемся на панель ODBC Microsoft Access SetUp, где в поле Datebase: появляется полный путь до базы данных и имя самой базы данных.

· Теперь в поле Data Source Name вводим псевдоним (короткий идентификатор) источника данных, который обозначит всё, что следует за Datebase:, т. е. путь до базы данных и имя самой базы.

· Теперь можно нажать OK и завершить установку драйвера и базы данных.

 

Темы заданий

 

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

 

Язык программирования: Java, СУБД - по выбору студента. Темы заданий приводятся в сокращенном виде.

1. Разработка HELP по Java на Java. Клиент запрашивает термин из БД на сервере находит ответ в БД-Help и пересылает его.

2. "Пакеты Java":  в ответ на запрос конкретного пакета (например, java.io или java.util) сервер должен из БД передавать

графический файл (jpg или gif) с иерархической структурой пакета.

3. "Классы Java": в ответ на запрос конкретного класса заданного пакета (например, applet.Applet или awt.Graphics) или метода

класса сервер должен из БД передавать файл с кодом класса или только метода (с комментариями на русском).

4. "СУБД". Обзор современных СУБД хранится в файлах на сервере. Клиент производит выбор конкретной СУБД по меню и в ответ на его запрос сервер передает файл с информацией по СУБД. Обеспечить пополнение сервера данными о новых СУБД.

5. Сервер-справочник (БД) по заданному преподавателем пакету классов (из src.jar). Обеспечить пополнение справочника новыми пакетами.

6. Центр дистанционного обучения. Клиент - студент, сервер –

ЦДО с БД.

7. Система "Выпускник каф. АСУ". Каф. АСУ – сервер, выпускники - клиенты, общаюшиеся с сервером, на котором в БД хранится информация о выпускниках и о кафедре.

8. "Метеослужба": запрос клиентом сводки погоды на заданный день недели и передача в ответ сервером из БД этой сводки.

Предусмотреть обновление сводки.

9. "Деканат": сервер хранит данные о студентах в БД и выдаёт

их клиентам-кафедрам в ответ на их запросы.

10. "Железная дорога" (предварительная покупка билетов на поезд).

11. "Рецепты" (на приготовление салатов, тортов, или сборов

целебных трав) – справочная служба Internet. Сервер должен осуществлять в БД поиск ответов на запросы клиентов по заданным ключевым словам или по меню. Обеспечить пополнение справочника новыми рецептами.

12. Любая тема, предложенная студентом и утвержденная пре-

подавателем.