Как изменить код Java для доступа к базе данных с использованием JDBC после создания пула соединений JDBC в GlassFish? - PullRequest
1 голос
/ 27 февраля 2012

Я новичок в JDBC. Я установил GlassFish 3.1.1 на Centos 6.2 и должен использовать его с приложением, которое подключается к базе данных Oracle 11G на другом сервере. Я прочитал документацию для GlassFish и думаю, что понимаю, как создать пул соединений JDBC, а также ресурс JDBC. У меня вопрос, как я могу использовать эту информацию при кодировании Java среднего уровня для подключения к базе данных?

В настоящее время (только с установкой GlassFish и без настройки JDBC) я полагаюсь на переменные среды CentOS для java (например, CLASSPATH), чтобы веб-приложение могло использовать драйверы JDBC. Однако я получаю следующую ошибку:

java.lang.NoClassDefFoundError: oracle/jdbc/pool/OracleDataSource 

Таким образом, моя попытка создать пул соединений JDBC и ресурс в GlassFish (чтобы приложение могло использовать драйвер JDBC). Мой файл Java начинается:

import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;

class JDBCexample {

    public static void main(String args[]) throws SQLException {
            Connection conn;
            Statement stmt;
            ResultSet rset;
            String query;
            String sqlString;

            String person_firstName;
            String person_lastName;
            String person_email;
            int person_salary;

            // connect to database
            OracleDataSource ds = new OracleDataSource();
            ds.setURL("jdbc:oracle:thin:myID/myPWD@192.168.0.1:1521:mySID");
            conn = ds.getConnection();

            // read something in database
            stmt = conn.createStatement();
            query = "SELECT first_name, last_name, email, salary FROM HR.Employees where rownum < 6";
            rset = stmt.executeQuery(query);
            while (rset.next()) {
                    person_firstName = rset.getString("first_name");
                    person_lastName = rset.getString("last_name");
                    person_email = rset.getString("email");
                    person_salary = rset.getInt("salary");
                    System.out.format(person_firstName + "  " + person_lastName + "  " + person_email + "  %d%n", person_salary) 
            }
and so on...

ВОПРОС: Как бы я изменил приведенный выше код после создания пула соединений JDBC (с именем: myPool) и ресурса JDBC (с именем: myDBPool)? Если это имеет значение, я использую Oracle 11.2, CentOS 6.2, GlassFish 3.1.1 с mod_jk и на веб-сервере Apache 2.2, JDK 1.6. У меня нет кластеризации или распределения нагрузки.

ОБНОВЛЕНИЕ 1: я думал, что эта ссылка была хорошим справочным материалом (см. Раздел под названием: «Создание экземпляра источника данных, регистрация в JNDI и подключение»). Но когда я изменяю указанный выше файл Java следующим образом (просто готовлю файл Java; еще не коснулся GlassFish),

// Add These:
import javax.naming.Context;
import javax.naming.InitialContext;

// Change from this:
// connect to database
    OracleDataSource ds = new OracleDataSource();
    ds.setURL("jdbc:oracle:thin:myID/myPWD@192.168.0.1:1521:mySID");
    conn = ds.getConnection();

// To this:
// connect to database
    Context ctext = new InitialContext();
    OracleDataSource ds = (OracleDataSource)ctext.lookup("jdbc/myDBPool");
    conn = ds.getConnection();

Я получаю ошибки:

JitterClass.java:67: unreported exception javax.naming.NamingException; must be caught or declared to be thrown
                    Context ctext = new InitialContext();
                                    ^
JitterClass.java:68: unreported exception javax.naming.NamingException; must be caught or declared to be thrown
                    OracleDataSource ds = (OracleDataSource)ctext.lookup("jdbc/myDBPool");
                                                                        ^

ОБНОВЛЕНИЕ 2: Я очистил эти ошибки компиляции, используя комментарии Кирилла ниже (чтобы выбросить все исключения). Затем я создал пул соединений JDBC и ресурс JDBC, и пинг прошел успешно. Итак, я запускаю приложение с клиента и наблюдаю следующую ошибку:

java.lang.ClassCastException : com.sun.gjc.spi.jdbc40.DataSource40 cannot be cast to oracle.jdbc.pool.OracleDataSource

На этом этапе, если я добавлю include javax.sql.DataSource в программу и изменим эту строку:

OracleDataSource ds = (OracleDataSource)ctext.lookup("jdbc/myDBPool");

чтобы стать этой строкой:

DataSource ds = (DataSource)ctext.lookup("jdbc/myDBPool");

компилируется без ошибок. Но теперь я в замешательстве ... разве мы не должны использовать OracleDataSource здесь? Или GlassFish каким-то образом реализует OracleDataSource, поскольку я вижу параметр для этого пула соединений для Datasource Classname, установленный на oracle.jdbc.pool.OracleDataSource (?). Надеясь, что кто-то может объяснить это.

Ответы [ 3 ]

2 голосов
/ 27 февраля 2012

Работает ли пинг в вашем пуле соединений? Если нет, проверьте конфигурацию вашего пула с http://docs.oracle.com/cd/E18930_01/html/821-2416/beamw.html#beanh

Когда пинг заработает и ресурс JDBC настроен, вы сможете получить к нему доступ в коде своего приложения через JNDI:

InitialContext context = new InitialContext();
DataSource ds = (DataSource) context.lookup("jdbc/myDBPool"); // or whatever name you used when creating the resource
conn = ds.getConnection();

Надеюсь, это поможет,

ОТВЕТ НА ОБНОВЛЕНИЕ 1: Это просто компилятор, говорящий вам формально перехватить или объявить проверенное исключение, которое может быть вызвано JNDI. В целях тестирования самый простой выход из этого (и будущие ошибки, подобные этой) - просто расширить сигнатуру вашего метода и выдать все исключения, т.е. * * 1010

ОТВЕТ НА ОБНОВЛЕНИЕ 2: Нет причин приводить интерфейсы JDBC к реализациям Oracle, если вам не требуется доступ к любой пользовательской функции, не указанной в спецификации JDBC. Цель DataSource - быть фабрикой для Connections, API которой определен в интерфейсе JDBC, так что это должно быть все, что вам нужно. Когда вы определяете пул соединений и ресурс в GlassFish, сервер приложений добавляет ценность, оборачивая классы драйвера JDBC и беспрепятственно проксируя их для вас, пока вы придерживаетесь импорта java.sql. *. Нет необходимости в импорте оракула :) Главное преимущество в том, что если вы когда-нибудь решите переключиться на MySQL или другое хранилище данных, ваш код будет переносимым и не нуждается в каких-либо изменениях.

1 голос
/ 27 февраля 2012

Чтобы добавить к хорошему ответу Кирилла:

Вместо поиска JNDI вы также можете использовать Внедрение ресурсов для настройки DataSource:

@Resource(name = "jdbc/Your_DB_Res")
private DataSource ds;

При запуске сервер приложений затем внедрит ресурс JDBC. В этом разделе Учебного руководства по Java EE есть больше по этому вопросу.

Используя внедрение ресурсов, вы можете уменьшить объем стандартного кода. Эта статья знакомит с понятиями.

0 голосов
/ 18 августа 2013

Помимо добавления драйвера в ваш classpath, вы должны попробовать добавить файл appserv-rt.jar в путь сборки вашего проекта (jar находится в каталоге lib Glassfish). Если вы не хотите включать все остальные jar-файлы, вам следует сначала создать библиотеку, содержащую jar appserv-rt, а затем добавить ее в путь сборки вашего проекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...