Главная » Java, Web » Базы данных в серверных компонентах EJB

0

В предыдущем разделе рассматривался поиск компонента EJ В в доступном окружении. Аналогичным способом можно работать с базами данных JDBC. Это стандартный метод доступа к базам JDBC, предоставляемый технологией EJB. Это позволяет контейнеру компонентов EJB наиболее эффективно работать, осуществляя доступ к базе данных наиболее продуктивно. Также это предоставляет возможность использования нескольких самостоятельных компонентов EJB при работе с транзакциями. В начале работы с компонентом EJB-сущности в файл инициализации компонентов EJB (файл ejb.ini) вставлялись сведения об источнике данных datasource с указанием его имени в виде nashiDannye. Этот источник данных будет автоматически доступен для JNDI, если записать следующую строчку:

j ava:camp/env/j dbc/NashiDannye

Но это лишь общий принцип. Конкретный вид обращения к базе данных будет зависеть от контейнера компонентов EJB. При подобном обращении мы получаем объект типа j avax. sqi. Datasource. Далее мы будем иметь возможность пользоваться методами этого объекта, в том числе методом getConnection (username, password), который возвращает привычный объект типа j ava.sql.Connection.

В качестве примера создадим компонент EJB-сессии, поддерживающий состояние, который будет работать с базой данных, откуда он будет получать информацию о стоимости акций. Создадим таблицу в базе данных Stocks С тремя столбцами, которые назовем ImyaAktsii, TsenaAktsii и KoiichastvoAktsij. Таблицу можно создать либо в уже использующейся базе данных, либо создать новую базу данных. Запишем в таблицу несколько строк, при этом одна и та же акция может быть записана несколько раз по разной цене.

Удаленный интерфейс будет содержать следующие дополнительные методы:

int getNumber() throws java.rmi.RemoteException, j ava.sql.SQLException, j avax.naming.NamingException; boolean buy(float maxPrice, int maxAmount) throws java.rmi.RemoteException, j ava.sql.SQLException, j avax.naming.NamingException; int getNumPurchased() throws java.rmi.RemoteException; float getPurchasePrice() throws java.rmi.RemoteException; Эти методы необходимо вставить вручную.

Метод get Price уже присутствует, но мы будем использовать java.sql.SQLException И j avax.naming.NamingException, ПОЭТОМУ необходимо изменить соответствующим образом код в файле удаленного интерфейса. Мы вставим в этот метод запросы к базе данных с использованием инструкции sql select с выводом минимальной цены для данной акции. Метод getNumber будет возвращать количество акций, предлагаемых по минимальной цене. Метод buy () будет использоваться для покупки указанного количества акций по указанной цене или дешевле. Если указанное количество покупаемых акций более, чем предложено к продаже, то будет куплено столько акций, сколько доступно. Количество купленных акций и стоимость покупки в дальнейшем могут быть определены при помощи методов

getNumPurchased () и getPurchasePrice (), наличием этих методов объясняется то, что данный компонент EJB будет иметь тип statefui.

Имплементация компонента EJB может быть представлена в следующем виде (листинг 5.20).

! Листинг 5.20. Файл BobAktsii.java

package stocks; import java.io.*; import java.sql.*; import javax.sql.*;

// класс компонента EJB-сессии "BobAktsii" impo rt j avax. e j b. *; impo rt j avax.naming.*; import java.rmi.*;

public class BobAktsiiBean implements javax.ejb.SessionBean { / / переменные

public String stock = null; int nPurchased = 0; float purchasePrice = 0.0F; // контекст сессии

javax.ejb.SessionContext ejbSessionContext = null; //методы get и set

public String getStock() throws java.rmi.RemoteException return stock;

public void setStock(String stock) throws java.rmi.RemoteException this.stock = stock;

public float getPrice () throws java.rmi.RemoteException, java.io.IOException, NamingException, SQLException

DataSource dataSource = (DataSource) (new InitialContext()).lookup("java:comp/env/jdbc/NashiDannye");

Connection con = dataSource.getConnection();

Statement stmt = con.createStatement ();

ResultSet rs = stmt.executeQuery("SELECT MIN(TsenaAktsii) FROM Stocks WHERE ImyaAktsii=’" + stock + "’");

if (! rs.next()) { stmt.close (); con.close ();

throw new java.rmi.RemoteException("Not found"); }

float result = rs.getFloat(1); stmt.close (); con.close (); if (result == 0.0)

throw new java.rmi.RemoteException("Not found");

return result; }

public int getNumber() throws java.rmi.RemoteException,

NamingException, SQLException {

DataSource dataSource = (DataSource) (new InitialContext()).lookup("java:comp/env/jdbc/nashiDannye");

Connection con = dataSource.getConnection();

Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery("SELECT KolichestvoAktsij FROM Stocks WHERE ImyaAktsii=’" + stock + "’ AND TsenaAktsii=(SELECT MIN(TsenaAktsii) FROM Stocks WHERE ImyaAktsii=’" + stock + ‘")");

if (! rs.next()) { stmt.close (); con.close ();

return 0; }

int result = rs.getInt(1); stmt.close (); con.close ();

return result; }

public boolean buy(float maxPrice, int maxAmount) throws

java.rmi.RemoteException, NamingException, SQLException {

// контейнер отвечает за транзакции

DataSource dataSource = (DataSource) (new InitialContext()).lookup("java:comp/env/jdbc/nashiDannye");

Connection con = dataSource.getConnection();

Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery("SELECT KolichestvoAktsij,TsenaAktsii FROM Stocks WHERE TsenaAktsii < " + maxPrice + " AND ImyaAktsii=’" + stock + "’ AND TsenaAktsii=(SELECT MIN(TsenaAktsii) FROM Stocks WHERE ImyaAktsii=’" + stock + "’)");

if (! rs.next()) { stmt.close (); con.close ();

return false; }

int number = rs.getInt(1); purchasePrice = rs.getFloat(2); rs.close();

if (number > maxAmount) {

int newNumber = number — maxAmount;

stmt.executeUpdate("UPDATE Stocks SET KolichestvoAktsij=" + newNumber + " WHERE TsenaAktsii=" + purchasePrice + " AND ImyaAktsii=’" + stock +

nPurchased = maxAmount; } else {

stmt.executeUpdate("DELETE FROM Stocks WHERE TsenaAktsii=" + purchasePrice + " AND ImyaAktsii=’" + stock + ‘"");

nPurchased = number; }

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

return true; }

public int getNumPurchased() throws java.rmi.RemoteException {

return nPurchased; }

public float getPurchasePrice() throws java.rmi.RemoteException {

return purchasePrice; }

11 метод ejbCreate по умолчанию public void ejbCreate( String stock

throws j avax.ej b.CreateExcept ion, java.rmi.RemoteException {

this.stock = stock; }

// прочие методы для ejbCreate

// прочие методы для компонента EJB-сущности

public void setSessionContext(javax.ejb.SessionContext ejbSessionContext)

throws RemoteException {

this.ejbSessionContext = ejbSessionContext; }

public void unsetSessionContext ()

throws RemoteException {

this.ejbSessionContext = null; }

public void ejbRemoveO

throws java.rmi.RemoteException, javax.ejb.EJBException {

// методы во время удаления экземпляра компонента EJB-сущности }

public void ejbActivate()

throws java.rmi.RemoteException {

// восстановление данных }

public void ejbPassivate()

throws java.rmi.RemoteException {

// сохранение данных }

Источник: Будилов В. А. Интернет-программирование на Java. — СПб.: БХВ-Петербург, 2003. — 704 е.: ил.

По теме:

  • Комментарии