Обратите внимание на то, как формируется адрес базы данных url. Он начинается со строки "jdbc:", потом записывается подпротокол (subprotocol), в данном примере используется мост JDBC-ODBC, поэтому записывается "odbc:". Далее указывается адрес (subname) по правилам подпротокола, здесь просто имя локальной базы "mydb". Второй и третий аргументы — это имя и пароль для соединения с базой данных.

Если в вашей вычислительной системе установлен пакет javax. sql, то вместо класса DriverManager лучше использовать интерфейс DataSource.

Связавшись с базой данных, можно посылать запросы. Запрос хранится в объекте, реализующем интерфейс statement. Этот объект создается методом createstatement (), описанным в интерфейсе connection. Например:

Statement st = con. createStatement();

Затем запрос (query) заносится в этот объект методом execute () и потом выполняется методом getResultSet(). В простых случаях это можно сделать одним методом executeQuery (), например:

ResultSet rs = st. executeQuery("SELECT name, code FROM tbll");

Здесь из таблицы tbll извлекается содержимое двух столбцов name и code и заносится в объект rs класса, реализующего интерфейс ResultSet.

SQL-операторы INSERT, UPDATE, DELETE, CREATE TABLE и другие в простых случаях ВЫПОЛНЯЮТСЯ методом executeUpdate ().

Остается методом next () перебрать элементы объекта rs — строки полученных столбцов — и извлечь данные многочисленными методами getxxx () интерфейса ResultSet:

while (rs. next()){

НЕ нашли? Не то? Что вы ищете?

emp[i] = rs. getString("name") ; 

num[i] = rs. getlnt("code");

i++;

}

Методы интерфейса ResuitsetMetaData позволяют узнать количество полученных столбцов, их имена и типы, название таблицы, имя ее владельца и прочие сведения о представленных в объекте rs сведениях.

Если объект st получен методом Statement:

St = con. createStatement(ResultSet. TYPE_SCROLL_SENSITIVE, ResultSet. CONCUR_OPDATABLE);

то можно перейти к предыдущему элементу методом previous (), к первому элементу — методом first о, к последнему — методом last о. Можно также изменять объект rs методами updatexxx () и даже изменять, удалять и добавлять соответствующие строки базы данных. Не все драйверы обеспечивают эти возможности, поэтому, надо проверить реальный тип объекта rs методами rs. getType() И rs. getConcurrency().

Интерфейс Statement расширен интерфейсом PreparedStatement, тоже позволяющим изменять объект ResultSet методами setxxxo.

Интерфейс PreparedStatement, в свою очередь, расширен интерфейсом Callablestatement, в котором описаны методы выполнения хранимых процедур.

12. RMI

Традиционный подход к выполнению кода на любой машине по сети сбивал с толку, а так же был утомителен и подвержен ошибкам при реализации. Лучший способ представить эту проблему - это думать, что какой-то объект живет на другой машине и что вы можете посылать сообщения удаленному объекту и получать результат, будто бы этот объект живет на вашей машине. Говоря простым языком, это в точности то, что позволяет делать Удаленный вызов методов (Remote Method Invocation (RMI) в Java. Этот раздел показывает шаги, необходимые для создания ваших собственных RMI.

12.1 Удаленный интерфейс

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

Когда вы создаете удаленный интерфейс, вы должны следовать следующей иснтрукции:

1.  Удаленный интерфейс должен быь публичным - public (он не может иметь “доступ на уровне пакета”, так же он не может быть “дружественным”). В противном случае клиенты будут получать ошибку при попытке загрузки объекта, реализующего удаленный интерфейс.

2.  Удаленный интерфейс должен расширять интерфейс java. rmi. Remote.

3.  Каждый метод удаленного интерфейса должен объявлять java. rmi. RemoteException в своем предложении throws в добавок к любым исключениям, специфичным для приложения.

4.  Удаленный объект, передаваемый как аргумент или возвращаемое значение (либо напрямую, либо как к части локального объекта), должен быть объявлен как удаленный интерфейс, а не реализация класса.

Ниже приведен простой удаленный интерфейс, представляющий сервис точного времени:

Листинг 24. Удаленный интерфейс PerfectTime.

import java. rmi.*;

interface PerfectTimeI extends Remote {

long getPerfectTime() throws RemoteException;

}

Он выглядит как любой другой интерфейс, за исключением того, что расширяет Remote и все его методы выбрасывают RemoteException. Помните, что interface и все его методы автоматически становятся public.

Реализация удаленного интерфейса

Сервер должен содержать класс, который расширяет UnicastRemoteObject и реализует удаленный интерфейс. Этот класс также может иметь другие методы, но для клиента доступны только методы удаленного интерфейса, так как клиент получает тоько ссылку на интерфейс, а не на класс, который его реализует.

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

Ниже приведена реализация удаленного интерфейса PerfectTimeI:

Листинг 25 Реализация удаленного объекта PerfectTime.

import java. rmi.*;

import java. rmi. server.*;

import java. rmi. registry.*;

import .*;

public class PerfectTime

extends UnicastRemoteObject

implements PerfectTimeI {

// Реализация интерфейса:

public long getPerfectTime()

throws RemoteException {

return System. currentTimeMillis();

}

// Должна быть реализация конструктора

// для выбрасывания RemoteException:

public PerfectTime() throws RemoteException {

// super(); // Вызывается автоматически

}

// Регистрация для обслуживания RMI. Выбрасывает

// исключения на консоль.

public static void main(String[] args)

throws Exception {

System. setSecurityManager(

new RMISecurityManager());

PerfectTime pt = new PerfectTime();

Naming. bind(

"//peppy:2005/PerfectTime", pt);

System. out. println("Ready to do time");

}

В этом примере main( ) обрабатывает все детали установки сервера. Когда вы обслуживаете RMI объект, в определенном месте вашей программы вы должны:

1.  Создать и установит менеджер безопасности, поддерживающий RMI. Как часть Java пакета, для RMI поддерживается только RMISecurityManager.

2.  Создать один или несколько экземпляров удаленного объекта. Здесь вы видите создание объекта PerfectTime.

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

12.2 Регистрация

В этом примере вы видите вызов статического метода Naming. bind( ). Однако этот вызов требует, чтобы регистрация была запущена отделным процессом на вашем компьютере. Имя сервера регистрации - это rmiregistry, и под 32-битной Windows вы говорите:

start rmiregistry

для запуска в фоновом режиме. Под Unix эта команда выглядит:

rmiregistry &

Как и многие другие сетевые программы, rmiregistry обращается по IP адресу машины, на которой она установлена, но она также слушает порт. Если вы вызовите rmiregistry как показано выше, без аргументов, будет использован порт по умолчанию 1099. Если вы хотите использовать другой порт, вы добавляете аргумент в командную строку, указывающий порт. Следующий пример устанавливает порт 2005, так что rmiregistry под управлением 32-битной Windows должна запускаться так:

start rmiregistry 2005

а подUnix:

rmiregistry 2005 &

Информаци о порте также должна передаваться в команде bind( ), наряду с IP адресом машины, где располагается регистрация. Но это может выявить огорчительную проблему, если вы хотите проверять RMI программы локально, как проверялись все программы до этой главы. В выпуске JDK 1.1.1, есть целая связка проблем:

1.  localhost не работает с RMI. Поэтому для экспериментов с RMI на одной машине вы должны использовать имя машины. Чтобы найти имя вашей машины под управлением 32-битной Windows, перейдите в панель управления и выберите “Network”. Выберите закладку “Identification”, и посмотрите имя вашего компьютера. В моем случае я назвал свой компьютер “Peppy”. Регистр в имени игнорируется.

2.  RMI не работает, пока ваш компьютер имеет активные TCP/IP соединения, даже если все ваши компоненты просто общаются друг с другом на локальной машине. Это значит, что вы должны соединятся с вашим провайдером Internet до того, как попробуете запустить программу или будете огорчены неким сообщением об ошибке.

Если учесть все это, команда bind( ) принимает вид:

Naming. bind("//peppy:2005/PerfectTime", pt);

Если вы используете порт по умолчанию 1099, вам не нужно указывать порт, так что вы можете просто сказать:

Naming. bind("//peppy/PerfectTime", pt);

Вы можете выполнить локальную проверку оставив в покое IP адрес, а использовать только идентификатор:

Naming. bind("PerfectTime", pt);

Имя сервиса здесь произвольно. В данном случае PerfectTime выбрано просто как имя класса, но вы можете назвать так, как захоите. Важно, чтобы это было уникальное имя регистрации, чтобы клиент знал, когда будет искать что производит удаленные объекты. Если имя уже зарегистрировано, вы получите AlreadyBoundException. Чтобы предотвратить это, вы всегда можете использовать rebind( ) вместо bind( ), так как rebind( ) либо добавляет новый элемент, либо заменяет уже существующий.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37