Java se сервлеты и jsp паттерны Gof junit Log4j ant



Pdf көрінісі
бет22/22
Дата11.12.2019
өлшемі8,99 Mb.
#53432
1   ...   14   15   16   17   18   19   20   21   22
Байланысты:
JAVA Methods Programming v2.march2015 (2)

часть кода, ответственная за передачу запросов в БД и обработку полученных 
от  нее  ответов.  Общее  определение  шаблона  Data  Access  Object  трактует  
его как прослойку между приложением и СУБД. DAO абстрагирует бизнес-
сущности  системы  и  отражает  их  на  записи  в  БД.  DAO  определяет  общие 
способы использования соединения с БД, моменты его открытия и закрытия 
или извлечения и возвращения в пул. В общем случае DAO можно опреде-
лять  таким  образом,  чтобы  была  возможность  подмены  одной  модели  базы 

JDBC
359
данных другой. Например: реляционную заменить на объектную или, что про-
ще, MySQL на Oracle. В практическом программировании такие глобальные 
задачи  ставятся  крайне  редко,  поэтому  будет  приведено  несколько  способов 
организации взаимодействия с БД, отличающихся уровнем использования кон-
некта к БД и организацией работы с бизнес-сущностями.
Вершина иерархии DAO представляет собой класс или интерфейс с описа-
нием общих методов, которые будут использоваться при взаимодействии с та-
блицей или группой таблиц. Как правило, это методы выбора, поиска сущно-
сти по признаку, добавление, удаление и замена информации.
/* # 7 # общие методы взаимодействия с моделью данных # AbstractDAO.java */
package
 by.bsu.simpledao;
import
 java.sql.Connection;
import
 java.sql.SQLException;
import
 java.sql.Statement;
import
 java.util.List;
import
 by.bsu.subject.Entity;
public
 abstract class AbstractDAO extends Entity> {
 
public
 abstract List findAll();
 
public
 abstract T findEntityById(K id);
 
public
 abstract boolean delete(K id);
 
public
 abstract boolean delete(T entity);
 
public
 abstract boolean create(T entity);
 
public
 abstract T update(T entity);
}
Набор методов может варьироваться в зависимости от логики приложения. 
Параметр K описывает, как правило, ключ в таблице, так как редкая таблица, 
содержащая описание сущности, обходится без первичного колюча. Параметр 
Entity определяет общую бизнес-сущность, от которой наследуются все биз-
нес-сущности  системы.  Класс  может  содержать  также  методы  возвращения 
соединения в пул или его закрытия, а также закрытия экземпляра Statement 
в виде:
public
 void close(Statement st) {
  try {
   if (st != null) {
    st.close();
   }
  } 
catch
 (SQLException e) {
   // лог о невозможности закрытия Statement
  }
 }
public
 void close(Connection connection) {
  try {
   if (connection != null) {
    connection.close();

ИСПОЛЬЗОВАНИЕ КЛАССОВ И БИБЛИОТЕК
360
   }
  } 
catch
 (SQLException e) {
 
 
 
// генерация исключения, т.к. нарушается работа пула
  }
 }
DAO. Уровень метода
Реализация DAO для конкретного бизнес-объекта имеет шанс выглядеть сле-
дующим образом. Часть методов может остаться нереализованной, кроме того, 
могут добавляться собственные методы, определить которые в более общем 
классе невозможно из-за узкой области применения. В данном случае это метод 
Abonent findAbonentByLastName(String name).
Реализация на уровне метода предполагает использование соединения для 
выполнения единственного запроса, т. е. соединение будет получено из пула 
в начале работы метода и возвращено по его окончании, что в общем случае 
не является экономным решением.
/* # 8 # конкретная реализация взаимодействия с моделью данных # AbonentDAO.java */
package
 by.bsu.simpledao;
import
 java.sql.Connection;
import
 java.sql.PreparedStatement;
import
 java.sql.ResultSet;
import
 java.sql.SQLException;
import
 java.sql.Statement;
import
 java.util.*;
import
 by.bsu.pool.ConnectionPool;
import
 by.bsu.subject.Abonent;
public
 class AbonentDAO extends AbstractDAO {
 
public
 static final String SQL_SELECT_ALL_ABONENTS = "SELECT * FROM phonebook";
 
public
 static final String SQL_SELECT_ABONENT_BY_LASTNAME = 
 
 
"SELECT idphonebook,phone FROM phonebook WHERE lastname=?";
 @Override
 
public
 List findAll() {
 
 
List abonents = new ArrayList<>();
 
 
Connection cn = null;
 
 
Statement st = null;
  try {
   cn 

ConnectionPool.getConnection();
   st 

cn.createStatement();
   ResultSet 
resultSet 

    st.executeQuery(SQL_SELECT_ALL_ABONENTS);
   while (resultSet.next()) {
    Abonent 
abonent 

new
 Abonent();
    abonent.setId(resultSet.getInt("idphonebook"));

JDBC
361
    abonent.setPhone(resultSet.getInt("phone"));
    abonent.setLastName(resultSet.getString("lastname"));
    abonents.add(abonent);
   }
  } 
catch
 (SQLException e) {
   System.err.println("SQL exception (request or table failed): " + e);
  } 
finally
 {
   close(st);
   // код возвращения экземпляра Connection в пул
  }
  return abonents;
 }
 @Override
 
public
 Abonent findEntityById(Integer id) {
  throw new UnsupportedOperationException();
 }
 @Override
 
public
 boolean delete(Integer id) {
  throw new UnsupportedOperationException();
 }
 @Override
 
public
 Abonent create(Abonent entity) {
  throw new UnsupportedOperationException();
 }
 @Override
 
public
 Abonent update(Abonent entity) {
  throw new UnsupportedOperationException();
 }
 
// собственный метод DAO
 
public
 Abonent findAbonentByLastName(String name) {
 
 
Abonent abonent = new Abonent(); 
 
 
Connection cn = null;
 
 
PreparedStatement st = null;
  try {
   cn 

ConnectionPool.getConnection();
   st 

   cn.prepareStatement(SQL_SELECT_ABONENT_BY_LASTNAME);
   st.setString(1, 
name);
   ResultSet 
resultSet 
=st.executeQuery();
   resultSet.next();
    abonent.setId(resultSet.getInt("idphonebook"));
    abonent.setPhone(resultSet.getInt("phone"));
    abonent.setLastName(name);
  } 
catch
 (SQLException e) {
   System.err.println("SQL exception (request or table failed): " + e);
  } 
finally
 {
   close(st);
   // код возвращения экземпляра Connection в пул
  
 
}
  return abonent;

ИСПОЛЬЗОВАНИЕ КЛАССОВ И БИБЛИОТЕК
362
 }
 @Override
 
public
 boolean delete(Abonent entity) {
  throw new UnsupportedOperationException();
 }
}
SQL-запросы размещаются в статических константах класса. В редких слу-
чаях запросы могут храниться вне системы в xml или properties файлах.
В данном примере использовался пул соединений, конфигурация которого 
задается в файле конфигурации context.xml.
/* # 9 # стандартный пул соединений # ConnectionPool.java */
package
 by.bsu.pool;
import
 java.sql.Connection;
import
 java.sql.SQLException;
import
 javax.naming.Context;
import
 javax.naming.InitialContext;
import
 javax.naming.NamingException;
import
 javax.sql.DataSource;
public
 class ConnectionPool {
    private
 static final String DATASOURCE_NAME = "jdbc/testphones";
    private static DataSource dataSource;
    static {
        try {
            Context initContext = new InitialContext();
            Context envContext = (Context) initContext.lookup("java:/comp/env");
            dataSource = (DataSource) envContext.lookup(DATASOURCE_NAME);
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
    private ConnectionPool() { }
    public static Connection getConnection() throws SQLException {
        Connection connection = dataSource.getConnection();
        return connection;
    }
// метод возвращения Connection в пул
}
Особенности конфигурирования и использования стандартного пула соеди-
нений приведены в конце главы 16.
DAO. Уровень класса
Реализация на уровне класса подразумевает использование одного коннекта 
к базе данных для вызова нескольких методов конкретного DAO класса. В этом 

JDBC
363
случае вершина иерархии DAO в качестве поля может объявлять сам коннект 
к СУБД или его оболочку, кроме стандартного набора методов, например:
/* # 10 # DAO с полем Connection # AbstractDAO.java */
package
 by.bsu.simpledao;
import
 java.sql.Statement;
import
 by.bsu.action.WrapperConnector;
public
 abstract class AbstractDAO {
protected
 WrapperConnector connector;
// методы добавления, поиска, замены, удаления
// методы закрытия коннекта и Statement
public
 void close() {
connector.closeConnection();
}
protected
 void closeStatement(Statement statement) {
connector.closeStatement(statement);
}
}
Реализация конкретного DAO при таком построении взаимодействия никог-
да в методе не должна закрывать соединение. Соединение закрывается в той 
части бизнес-логики, откуда выполняются обращения к DAO. 
/* # 11 # DAO уровне класса # AbonentDAO.java */
package
 by.bsu.simpledao;
import
 java.sql.ResultSet;
import
 java.sql.SQLException;
import
 java.sql.Statement;
import
 java.util.*;
import
 by.bsu.action.WrapperConnector;
import
 by.bsu.subject.Abonent;
public
 class AbonentDAO extends AbstractDAO {
public
 static final String SQL_SELECT_ALL_ABONENTS = "SELECT * FROM phonebook";
"SELECT * FROM phonebook";
public
 AbonentDAO() {
this.connector = new WrapperConnector();
}
public
 List findAll() {
List abonents = new ArrayList<>(); 
Statement st = null;
try
 {
st = connector.getStatement()
ResultSet resultSet = st.executeQuery(SQL_SELECT_ALL_ABONENTS); 
while
 (resultSet.next()) {
Abonent abonent  new
=   Abonent();
abonent.setId(resultSet.getInt("idphonebook")); 
abonent.setPhone(resultSet.getInt("phone"));

ИСПОЛЬЗОВАНИЕ КЛАССОВ И БИБЛИОТЕК
364
abonent.setLastName(resultSet.getString("lastname")); 
abonents.add(abonent);
}
catch
}   (SQLException e) {
System.err.println("SQL exception (request or table failed): " + e); 
finally {
this
.closeStatement(st);
}
return
 abonents;
}
// другие методы
}
Соединение с базой данных инициирует конструктор DAO, либо получает 
его из пула. В методе остаются возможности по созданию экземпляра Statement 
для выполнения запросов и его закрытию. В данной реализации использовался 
класс-обертка для соединения, инкапсулирующий процесс создания соедине-
ния и упрощающий его использование. Такой подход при организации пула 
соединений из экземпляров классов-оберток резко затрудняет попадание в пул 
«диких» соединений, созданных программистом в обход пула.
/* # 12 # класс-оболочка соединения # WrapperConnector.java */
package
 by.bsu.action;
import
 java.sql.Connection;
import
 java.sql.DriverManager;
import
 java.sql.Statement;
import
 java.sql.SQLException;
import
 java.util.MissingResourceException;
import
 java.util.Properties;
import
 java.util.ResourceBundle;
public
 class WrapperConnector {
private
 Connection connection; 
public
 WrapperConnector() {
try
 {
ResourceBundle resource = ResourceBundle.getBundle("resource.database");
String url = resource.getString("url");
String user = resource.getString("user");
String pass = resource.getString("password"); 
Properties prop  new
=   Properties();
prop.put("user", user);
prop.put("password", pass);
connection = DriverManager.getConnection(url, prop);
catch
}   (MissingResourceException e) {
System.err.println("properties file is missing " + e); 
catch
}   (SQLException e) {
System.err.println("not obtained connection " + e);
}

JDBC
365
}
public
 Statement getStatement() throws SQLException {
if
 (connection != null) {
Statement statement = connection.createStatement();
if
 (statement != null) {
return
 statement;
}
}
throw
 new SQLException("connection or statement is null");
}
public
 void closeStatement(Statement statement) {
if
 (statement != null) {
try
 {
statement.close();

catch
 (SQLException e) {
System.err.println("statement is null " + e);
}
}
}
public
 void closeConnection() {
if
 (connection != null) {
try
 {
connection.close();

catch
 (SQLException e) {
System.err.println(" wrong connection" + e);
}
}
}
// другие необходимые делегированные методы интерфейса Connection
}
DAO. Уровень логики
На практике чаще всего возникает необходимость при выполнении запроса 
пользователя обращаться сразу к нескольким ветвям DAO и использовать при 
этом единственное соединение с БД. В этом случае соединение с БД создается 
или извлекается из пула до создания экземпляров DAO, а закрывается, соответ-
ственно, после выполнения всех обращений к БД.
/* # 13 # DAO с полем Connection без прямой инициализации # AbstractDAO.java */
package
 by.bsu.simpledao;
import
 java.sql.Connection;
import
 java.sql.SQLException;
import
 java.sql.Statement;
import
 java.util.List;
import
 by.bsu.subject.Entity;

ИСПОЛЬЗОВАНИЕ КЛАССОВ И БИБЛИОТЕК
366
public
 abstract class AbstractDAO extends Entity> {
protected
 Connection connection; 
public
 AbstractDAO(Connection connection) {
this
.connection = connection;
}
public
 abstract List findAll();
public
 abstract T findEntityById(int id);
public
 abstract boolean delete(int id);
public
 abstract boolean delete(T entity);
public
 abstract boolean create(T entity);
public
 abstract T update(T entity);
public
 void close(Statement st) {
try
 {
if
 (st != null) {
st.close();
}

catch
 (SQLException e) {
// лог о невозможности закрытия Statement
}
}
}
/* # 14 # примерные реализации DAO # AbonentDAO.java # PaymentDAO.java */
package
 by.bsu.simpledao;
import
 java.sql.Connection;
import
 java.sql.PreparedStatement;
import
 java.sql.ResultSet;
import
 java.sql.SQLException;
import
 java.sql.Statement;
import
 java.util.*;
import
 by.bsu.subject.Abonent;
public
 class AbonentDAO extends AbstractDAO {
public
 AbonentDAO(Connection connection) {
super
(connection); 
}
// реализации методов
}
package
 by.bsu.simpledao;
import
 java.sql.Connection;
import
 java.util.List;
import
 by.bsu.subject.Payment;
public
 class PaymentDAO extends AbstractDAO
{
public
 PaymentDAO(Connection connection) {
super
(connection); 
}
// реализации методов
}
где Payment представляет класс-сущность в виде подкласса класса Entity.

JDBC
367
Схематически применение этого подхода можно увидеть в методе doLogic() 
класса SomeLogic.
/* # 15 # использование DAO на уровне логики # SomeLogic.java */
package
 by.bsu.logic;
import
 java.sql.Connection;
import
 java.sql.SQLException;
import
 by.bsu.pool.ConnectionPool;
import
 by.bsu.simpledao.AbonentDAO;
import
 by.bsu.simpledao.PaymentDAO;
import
 by.bsu.subject.Abonent;
import
 by.bsu.subject.Payment;
public
 class SomeLogic {
public
 void doLogic(int id) throws SQLException {
// 1. создание-получение соединения
Connection 
conn
 = ConnectionPool.getConnection();
// 2. открытие транзакции
conn.setAutoCommit(false);
// 3. инициализация необходимых экземпляров DAO
AbonentDAO abonentDAO = new AbonentDAO(conn);
PaymentDAO paymentDAO = new PaymentDAO(conn);
// 4. выполнение запросов
abonentDAO.findAll();
paymentDAO.findEntityById(id);
paymentDAO.delete(id);
// 
5. 
закрытие транзакции
conn.commit();
// 6. закрытие-возвращение соединения
ConnectionPool.close(conn);
}
}
Задания к главе 12
Вариант А
В каждом из заданий необходимо выполнить следующие действия:
• организацию соединения с базой данных вынести в отдельный класс, метод
которого возвращает соединение;
• создать БД. Привести таблицы к одной из нормированных форм;
• создать класс для выполнения запросов на извлечение информации из БД
с использованием компилированных запросов;
• создать класс на модификацию информации.
1. Файловая система. В БД хранится информация о дереве каталогов файло-
вой системы — каталоги, подкаталоги, файлы.
Для каталогов необходимо хранить:

ИСПОЛЬЗОВАНИЕ КЛАССОВ И БИБЛИОТЕК
368
— родительский каталог;
— название.
Для файлов необходимо хранить:
— родительский каталог;
— название;
— место, занимаемое на диске.
• Определить полный путь заданного файла (каталога).
• Подсчитать количество файлов в заданном каталоге, включая вложенные
файлы и каталоги.
• Подсчитать место, занимаемое на диске содержимым заданного каталога.
• Найти в базе файлы по заданной маске с выдачей полного пути.
• Переместить файлы и подкаталоги из одного каталога в другой.
• Удалить файлы и каталоги заданного каталога.
2. Видеотека. В БД хранится информация о домашней видеотеке: фильмы,
актеры, режиссеры.
Для фильмов необходимо хранить:
— название;
— имена актеров;
— дату выхода;
— страну, в которой выпущен фильм.
Для актеров и режиссеров необходимо хранить:
— ФИО;
— дату рождения.
• Найти все фильмы, вышедшие на экран в текущем и прошлом году.
• Вывести информацию об актерах, снимавшихся в заданном фильме.
• Вывести информацию об актерах, снимавшихся как минимум в N филь-
мах.
• Вывести информацию об актерах, которые были режиссерами хотя бы
одного из фильмов.
• Удалить все фильмы, дата выхода которых была более заданного числа
лет назад.
3. Расписание занятий. В БД хранится информация о преподавателях и про-
водимых ими занятиях.
Для предметов необходимо хранить:
— название;
— время проведения (день недели);
— аудитории, в которых проводятся занятия.
Для преподавателей необходимо хранить:
— ФИО;
— предметы, которые он ведет;
— количество пар в неделю по каждому предмету;
— количество студентов, занимающихся на каждой паре.

JDBC
369
• Вывести информацию о преподавателях, работающих в заданный день
недели в заданной аудитории.
• Вывести информацию о преподавателях, которые не ведут занятия в за-
данный день недели.
• Вывести дни недели, в которых проводится заданное количество заня-
тий.
• Вывести дни недели, в которых занято заданное количество аудиторий.
• Перенести первые занятия заданных дней недели на последнее место.
4. Письма. В БД хранится информация о письмах и отправляющих их людях.
Для людей необходимо хранить:
— ФИО;
— дату рождения.
Для писем необходимо хранить:
— отправителя;
— получателя;
— тему письма;
— текст письма;
— дату отправки.
• Найти пользователя, длина писем которого наименьшая.
• Вывести информацию о пользователях, а также количестве полученных
и отправленных ими письмах.
• Вывести информацию о пользователях, которые получили хотя бы одно
сообщение с заданной темой.
• Вывести информацию о пользователях, которые не получали сообщения
с заданной темой.
• Направить письмо заданного человека с заданной темой всем адресатам.
5. Сувениры. В БД хранится информация о сувенирах и их производителях.
Для сувениров необходимо хранить:
— название;
— реквизиты производителя;
— дату выпуска;
— цену.
Для производителей необходимо хранить:
— название;
— страну.
• Вывести информацию о сувенирах заданного производителя.
• Вывести информацию о сувенирах, произведенных в заданной стране.
• Вывести информацию о производителях, чьи цены на сувениры меньше
заданной.
• Вывести  информацию  о  производителях  заданного  сувенира,  произве-
денного в заданном году.
• Удалить заданного производителя и его сувениры.

ИСПОЛЬЗОВАНИЕ КЛАССОВ И БИБЛИОТЕК
370
6. Заказ. В БД хранится информация о заказах магазина и товарах в них.
Для заказа необходимо хранить:
— номер заказа;
— товары в заказе;
— дату поступления.
Для товаров в заказе необходимо хранить:
— товар;
— количество.
Для товара необходимо хранить:
— название;
описание;
— цену.
• Вывести полную информацию о заданном заказе.
• Вывести номера заказов, сумма которых не превосходит заданную и ко-
личество различных товаров равно заданному.
• Вывести номера заказов, содержащих заданный товар.
• Вывести номера заказов, не содержащих заданный товар и поступивших
в течение текущего дня.
• Сформировать новый заказ, состоящий из товаров, заказанных в теку-
щий день.
• Удалить все заказы, в которых присутствует заданное количество задан-
ного товара.
7. Продукция. В БД хранится информация о продукции компании.
Для продукции необходимо хранить:
— название;
— группу продукции (телефоны, телевизоры и др.);
— описание;
— дату выпуска;
— значения параметров.
Для групп продукции необходимо хранить:
— название;
— перечень групп параметров (размеры и др.).
Для групп параметров необходимо хранить:
— название;
— перечень параметров.
Для параметров необходимо хранить:
— название;
— единицу измерения.
• Вывести перечень параметров для заданной группы продукции.
• Вывести перечень продукции, не содержащий заданного параметра.
• Вывести информацию о продукции для заданной группы.
• Вывести информацию о продукции и всех ее параметрах со значениями.

JDBC
371
• Удалить из базы продукцию, содержащую заданные параметры.
• Переместить группу параметров из одной группы товаров в другую.
8. Погода. В БД хранится информация о погоде в различных регионах.
Для погоды необходимо хранить:
— регион;
— дату;
— температуру;
— осадки.
Для регионов необходимо хранить:
— название;
— площадь;
— тип жителей.
Для типов жителей необходимо хранить:
— название;
— язык общения.
• Вывести сведения о погоде в заданном регионе.
• Вывести даты, когда в заданном регионе шел снег и температура была
ниже заданной отрицательной.
• Вывести информацию о погоде за прошедшую неделю в регионах, жите-
ли которых общаются на заданном языке.
• Вывести среднюю температуру за прошедшую неделю в регионах с пло-
щадью больше заданной.
9. Магазин часов. В БД хранится информация о часах, продающихся в магазине.
Для часов необходимо хранить:
— марку;
— тип (кварцевые, механические);
— цену;
— количество;
— реквизиты производителя.
Для производителей необходимо хранить:
— название;
— страна.
• Вывести марки заданного типа часов.
• Вывести информацию о механических часах, цена на которые не превы-
шает заданную.
• Вывести марки часов, изготовленных в заданной стране.
• Вывести производителей, общая сумма часов которых в магазине не пре-
вышает заданную.
10. Города. В БД хранится информация о городах и их жителях.
Для городов необходимо хранить:
— название;
— год основания;

ИСПОЛЬЗОВАНИЕ КЛАССОВ И БИБЛИОТЕК
372
— площадь;
— количество населения для каждого типа жителей.
Для типов жителей необходимо хранить:
— город проживания;
— название;
— язык общения.
• Вывести информацию обо всех жителях заданного города, разговарива-
ющих на заданном языке.
• Вывести информацию обо всех городах, в которых проживают жители
выбранного типа.
• Вывести  информацию  о  городе  с  заданным  количеством  населения
и всех типах жителей, в нем проживающих.
• Вывести информацию о самом древнем типе жителей.
11. Планеты. В БД хранится информация о планетах, их спутниках и галак-
тиках.
Для планет необходимо хранить:
— название;
— радиус;
— температуру ядра;
— наличие атмосферы;
— наличие жизни;
— спутники.
Для спутников необходимо хранить:
— название;
— радиус;
— расстояние до планеты.
Для галактик необходимо хранить:
— название;
— планеты.
• Вывести  информацию  обо  всех  планетах,  на  которых  присутствует
жизнь, и их спутниках в заданной галактике.
• Вывести информацию о планетах и их спутниках, имеющих наимень-
ший радиус и наибольшее количество спутников.
• Вывести  информацию  о  планете,  галактике,  в  которой  она  находится,
и ее спутниках, имеющей максимальное количество спутников, но с на-
именьшим общим объемом этих спутников.
• Найти галактику, сумма ядерных температур планет которой наибольшая.
12. Точки. В БД хранится некоторое конечное множество точек с их координа-
тами.
• Вывести точку из множества, наиболее приближенную к заданной.
• Вывести точку из множества, наиболее удаленную от заданной.
• Вывести точки из множества, лежащие на одной прямой с заданной прямой.

JDBC
373
13. Треугольники. В БД хранятся треугольники и координаты их точек на пло-
скости.
• Вывести треугольник, площадь которого наиболее приближена к заданной.
• Вывести треугольники, сумма площадей которых наиболее приближена
к заданной.
• Вывести  треугольники,  которые  помещаются  в  окружность  заданного
радиуса.
14. Словарь. В БД хранится англо-русский словарь, в ко тором для одного англий-
ского слова может быть указано нес колько его значений и наоборот. Со сторо-
ны клиента вводятся последовательно английские (русские) слова. Для каждо-
го из них вывести на консоль все русские (английские) значения слова.
15. Словари. В двух различных базах данных хранятся два словаря: русско-
белорусский и белорусско-русский. Клиент вводит слово и выбирает язык.
Вывести перевод этого слова.
16. Стихотворения. В БД хранятся несколько стихотворений с указанием ав-
тора и года создания. Для хранения стихотворений использовать объекты
типа Blob. Клиент выбирает автора и критерий поиска.
• В каком из стихотворений больше всего восклицательных предложений?
• В каком из стихотворений меньше всего повествовательных предложений?
• Есть ли среди стихотворений сонеты и сколько их?
17. Четырехугольники. В БД хранятся координаты вершин выпуклых четы-
рехугольников на плоскости.
• Вывести координаты вершин параллелограммов.
• Вывести координаты вершин трапеций.
18. Треугольники. В БД хранятся координаты вершин треугольников на пло-
скости.
• Вывести все равнобедренные треугольники.
• Вывести все равносторонние треугольники.
• Вывести все прямоугольные треугольники.
• Вывести все тупоугольные треугольники с площадью больше заданной.
Вариант B
Для заданий варианта В гл. 4 создать базу данных для хранения информа-
ции.  Определить  класс  для  организации  соединения  (пула  соединений). 
Создать классы для выполнения соответствующих заданию запросов в БД. 
Тестовые задания к главе 12
Вопрос 12.1.
Какие пакеты содержат интерфейсы и классы JDBC (1)?
1) java.db и javax.db
2) java.sql и javax.sql

ИСПОЛЬЗОВАНИЕ КЛАССОВ И БИБЛИОТЕК
374
3) java.jdbc.sql и javax.jdbc.sql
4) org.sql и org.jdbc
5) java.jdbc и javax.jdbc
Вопрос 12.2.
Даны операторы языка Java:
a) Connection cn =
DriverManager.getConnection("jdbc:mysql://localhost:3306", "root", "pass");
b) ResultSet rs = st.executeQuery("SELECT * FROM users WHERE id=1");
c) Class.forName("org.gjt.mm.mysql.Driver");
d) Statement st = cn.createStatement();
e) System.out.println(rs.next());
Расставьте их в правильной последовательности так, чтобы с помощью по-
лучившегося кода можно было извлечь данные из БД (1):
1) abdec;
2) cadbe;
3) cabde;
4) ebdac;
5) abced.
Вопрос 12.3.
Какие типы statement-объектов существуют в JDBC (3)?
1) Statement
2) ResultStatement
3) PreparedStatement
4) DriverStatement
5) MetaDataStatement
6) CallableStatement
Вопрос 12.4.
Дана база данных test c таблицей users:
id
name
1
Ivanov
Какая информация добавится в таблицу users после выполнения следующе-
го кода (2)?
Connection cn = /* корректное получение соединения */;
Statement st = cn.createStatement();
st.executeUpdate("INSERT INTO users VALUES (2, 'Petrov')");
cn.setAutoCommit(false);

JDBC
st.executeUpdate("INSERT INTO users VALUES (3, 'Sidorov')");
cn.setSavepoint("point1");
st.executeUpdate("INSERT INTO users VALUES (4, 'Vasechkin')");
cn.rollback();
st.executeUpdate("INSERT INTO users VALUES (5, 'Blinov')");
cn.commit();
1) id=2, name=Petrov
2) id=3, name=Sidorov
3) id=4, name=Vasechkin
4) id=5, name=Blinov
Вопрос 12.5.
Укажите, каким способом можно выполнить хранимую процедуру с помо-
щью JDBC (3):
1) вызвать метод execute() на объекте CallableStatement
2) вызвать метод executeQuery() на объекте CallableStatement
3) вызвать метод executeUpdate() на объекте CallableStatement
4) вызвать метод executeProcedure() на объекте CallableStatement
5) вызвать метод execute() на объекте StoredStatement
6) вызвать метод executeQuery() на объекте StoredStatement
7) вызвать метод executeUpdate() на объекте StoredStatement
8) вызвать метод executeProcedure() на объекте StoredStatement

376
Глава 13
СЕТЕВЫЕ ПРОГРАММЫ
Если неправильно набрать номер,  
никогда не будет гудков «занято».
Загадка Ковака
Поддержка Интернета
Язык Java делает сетевое программирование простым благодаря наличию 
специальных средств и классов. Большинство этих классов находится в пакете 
java.net. Сетевые классы имеют методы для установки сетевых соединений 
передачи  запросов  и  сообщений.  Многопоточность  позволяет  обрабатывать 
несколько  соединений.  Сетевые  приложения  используют  интернет-приложе-
ния, к которым относятся веб-браузер, e-mail, сетевые новости, передача фай-
лов. Для создания таких приложений используются сокеты, порты, протоколы 
TCP/IP, UDP.
Приложения клиент/сервер используют компьютер, выполняющий специ-
альную  программу-сервер,  которая  обычно  устанавливается  на  удаленном 
компьютере и предоставляет услуги другим программам-клиентам. Клиент — 
это программа, получающая услуги от сервера. Клиент устанавливает соедине-
ние с сервером и пересылает серверу запрос. Сервер осуществляет прослуши-
вание  клиентов,  получает  и  выполняет  запрос  после  установки  соединения. 
Результат  выполнения  запроса  может  быть  возвращен  сервером  клиенту. 
Запросы и сообщения представляют собой записи, структура которых опреде-
ляется используемыми протоколами.
В стеке протоколов TCP/IP используются следующие прикладные прото-
колы:
HTTP(s) — Hypertext Transfer Protocol (WWW);
NNTP — Network News Transfer Protocol (группы новостей);
SMTP — Simple Mail Transfer Protocol (посылка почты);
POP
3 — Post Office Protocol (чтение почты с сервера);
FTP — File Transfer Protocol (протокол передачи файлов).
Каждый  компьютер  из  подключенных  к  сети  по  протоколу TCP/IP  имеет 
уникальный IP-адрес, используемый для идентификации и установки соедине-
ния. IP-адрес существует в двух видах: IPv4 и IPv6. Формат IPv4 представлен 
32-битовым  числом,  обычно  записываемым  как  четыре  числа,  разделенные 

СЕТЕВЫЕ ПРОГРАММЫ
377
точками, каждое из которых изменяется от 0 до 255, например 217.21.43.10
Формат IPv6 представлен 128-битовым числом, обычно записываемым как во-
семь  шестнадцатеричных  чисел,  разделенных  двоеточиями,  например 
1170:0:0:0:7:771:100А:214B.  IP-адрес  может  быть  временным  и  выделяться 
динамически для каждого подключения или быть постоянным, как для серве-
ра. IP-адреса используются во внутренних сетевых системах. Обычно при под-
ключении к Интернету вместо числового IP-адреса используются символьные 
имена  (например:  www.bsu.by),  называемые  именами  домена.  Специальная 
программа DNS (Domain Name Server), располагаемая на отдельном сервере, 
проверяет адрес и преобразует имя домена в числовой IP-адрес. Если в качест-
ве сервера используется этот же компьютер без сетевого подключения, в каче-
стве IP-адреса указывается 127.0.0.1 или localhost. Для явной идентификации 
услуг  к  IP-адресу  присоединяется  номер  порта  через  двоеточие,  например 
217.21.43.10:443. Здесь указан номер порта 443. Номера портов от 1 до 1024 
могут быть заняты для внутреннего использования, например, если порт явно 
не указан, браузер воспользуется значением по умолчанию: 20  FTP-данные, 
21  FTP-управление, 53  DNS, 80  HTTP, 25  SMTP, 110  POP3, 
119  NNTP. К серверу можно подключиться с помощью различных портов. 
Каждый порт указывает конкретное место соединения на указанном компьюте-
ре и предоставляет определенную услугу.
Для доступа к интернет-ресурсу в браузере указывается адрес URL. Адрес 
URL (Universal Resource Locator) состоит из двух частей — префикса протоко-
ла (http, https, ftp и т. д.) и URI (Universal Resource Identifier). URI содержит 
интернет-адрес, необязательный номер порта и путь к каталогу, содержащему 
файл, например:
http://www.oracle.com/download.jsp
URI не может содержать такие специальные символы, как пробелы, табуля-
ции,  возврат  каретки.  Их  можно  задавать  через  шестнадцатеричные  коды. 
Например: %20 обозначает пробел. Другие зарезервированные символы: сим-
вол & — разделитель аргументов, символ следует перед аргументами запро-
сов,  символ  +  —  пробел,  символ  #  —  ссылки  внутри  страницы,  например  
имя_страницы#имя_ссылки.
Определить  IP-адрес  в  приложеннии  можно  с  помощью  объекта  класса 
java.net.InetAddress.  Можно  также  использовать  и  специфические  классы 
Inet4Address и Inet6Address.
Класс InetAddress не имеет public-конструкторов. Создать объект класса 
можно  с  помощью  статических  методов.  Метод  getLocalHost()  возвращает 
объект класса InetAddress, содержащий IP-адрес и имя компьютера, на кото-
ром выполняется программа. Метод getByName(String host) возвращает объ-
ект класса InetAddress, содержащий IP-адрес по имени компьютера, используя 
пространство  имен  DNS.  IP-адрес  может  быть  временным,  различным  для 

ИСПОЛЬЗОВАНИЕ КЛАССОВ И БИБЛИОТЕК
378
каждого соединения, однако он остается постоянным, если соединение уста-
новлено. Метод getByAddress(byte[] addr) создает объект класса InetAddress
содержащий имя компьютера, по IP-адресу, представленному в виде массива 
байт.  Если  компьютер  имеет  несколько  IP,  то  получить  их  можно  методом 
getAllByName(String  host),  возвращающим  массив  объектов  класса 
InetAddress.  Если  IP  для  данной  машины  один,  то  массив  будет  содержать 
один  элемент.  Метод  getByAddress(String  host,  byte[]  addr)  создает  объект 
класса InetAddress с заданным именем и IP-адресом, не проверяя существова-
ние такого компьютера. Все эти методы являются потенциальными генератора-
ми  исключительной  ситуации  UnknownHostException,  и  поэтому  их  вызов 
должен  быть  обработан  с  помощью  throws  для  метода  или  блока  try-catch
Проверить доступ к компьютеру в данный момент можно с помощью метода 
boolean isReachable(int timeout), который возвращает true, если компьютер до-
ступен, где timeout — время ожидания ответа от компьютера в миллисекундах. 
Следующая  программа  демонстрирует  при  наличии  Internet-соединения, 
как получить IP-адрес текущего компьютера и IP-адрес из имени домена с по-
мощью сервера имен доменов (DNS), к которому обращается метод getByName() 
класса InetAddress.
/* # 1 # вывод IP-адреса компьютера и Интернет-ресурса # InetLogic.java*/
package
 by.bsu.net;
import
 java.net.InetAddress;
public
 class InetLogic {
public
 static void main(String[] args) {
InetAddress currentIP = null;
InetAddress bsuIP = null;
try
 {
currentIP 

InetAddress.getLocalHost();
// вывод IP-адреса локального компьютера
System.out.println("Мой IP -> " + currentIP.getHostAddress());
bsuIP 

InetAddress.getByName("www.bsu.by");
// вывод IP-адреса БГУ www.bsu.by
System.out.println("BSU -> " + bsuIP.getHostAddress());

catch
 (UnknownHostException e) {
// если не удается найти IP
System.err.println("адрес недоступен " + e);
}
}
}
В результате будет выведено, например: 
Мой IP -> 172.17.16.14
BSU -> 217.21.43.10
Метод getLocalHost() класса InetAddress создает объект currentIP и воз-
вращает IP-адрес компьютера.

СЕТЕВЫЕ ПРОГРАММЫ
379
/* # 2 # присваивание фиктивного имени реальному ресурсу, заданному через IP # 
UnCheckedHost.java */
package
 by.bsu.net;
import
 java.io.IOException;
import
 java.net.InetAddress;
import
 java.net.UnknownHostException;
public
 class UnCheckedHost {
public
 static void main(String[] args) {
// задание IP-адреса в виде массива
byte
 ip[] ={(byte)217, (byte)21, (byte)43, (byte)10}; 
try
 {
InetAddress addr = InetAddress.getByAddress("University", ip);
System.out.println(addr.getHostName() 
  + "-> cоединение:" + addr.isReachable(1000));

catch
 (UnknownHostException e) {
System.err.println("адрес недоступен " + e);

catch
 (IOException e) {
System.err.println("ошибка потока " + e);
}
}
}
В результате будет выведено в случае подключения к сети Интернет: 
University-> cоединение:true
Для доступа к ресурсам можно создать объект класса URL, указывающий 
на ресурсы в Интернете. В следующем примере объект URL используется для 
доступа к HTML-файлу, на который он указывает и отображает его в окне бра-
узера с помощью метода showDocument().
/* # 3 # запуск страницы из апплета # ShowDocument.java */
package
 by.bsu.net;
import
 java.awt.Graphics;
import
 java.net.MalformedURLException;
import
 java.net.URL;
import
 javax.swing.JApplet;
public
 class ShowDocument extends JApplet {
private 
URL bsu = null
public
 String getBaseURL() {
return
 "http://www.bsu.by";
}
public
 void paint(Graphics g) {
int
 timer = 0;
g.drawString("Загрузка страницы", 10, 10);
try
 {
for
 (; timer < 30; timer++) {
g.drawString(".", 10 + timer * 5, 25);

ИСПОЛЬЗОВАНИЕ КЛАССОВ И БИБЛИОТЕК
380
     Thread.sleep(100);
}
bsu 

new
 URL(getBaseURL());
this
.getAppletContext().showDocument(bsu, "_blank");

catch
 (InterruptedException e) {
e.printStackTrace();
catch (MalformedURLException e) {
// некорректно задан протокол, доменное имя или путь к файлу
e.printStackTrace();
}
}

Метод showDocument() может содержать параметры для отображения стра-
ницы различными способами: «_self»  — выводит документ в текущий фрейм, 
«_blank» — в новое окно, «_top» — на все окно, «_parent» — в родительском 
окне, «имя_окна» — в окне с указанным именем. Для корректной работы дан-
ного  примера  апплет  следует  запускать  из  браузера,  используя  следующий 
HTML-документ:




Достарыңызбен бөлісу:
1   ...   14   15   16   17   18   19   20   21   22




©www.engime.org 2024
әкімшілігінің қараңыз

    Басты бет