Oracle 在GlassFish中创建JDBC连接池后,如何更改Java代码以使用JDBC访问数据库?

Oracle 在GlassFish中创建JDBC连接池后,如何更改Java代码以使用JDBC访问数据库?,oracle,jdbc,glassfish,Oracle,Jdbc,Glassfish,我是JDBC新手。我已经在Centos 6.2上安装了GlassFish 3.1.1,需要将其与连接到另一台服务器上的Oracle 11G数据库的应用程序一起使用。我已经阅读了GlassFish的文档,并且认为我理解了如何创建JDBC连接池和JDBC资源。我的问题是,在编写java中间层连接到数据库的代码时,如何使用这些信息 目前(只有GlassFish安装,没有JDBC配置),我依靠CentOS java环境变量(如CLASSPATH)来允许web应用程序使用JDBC驱动程序。但是,我得到了以

我是JDBC新手。我已经在Centos 6.2上安装了GlassFish 3.1.1,需要将其与连接到另一台服务器上的Oracle 11G数据库的应用程序一起使用。我已经阅读了GlassFish的文档,并且认为我理解了如何创建JDBC连接池和JDBC资源。我的问题是,在编写java中间层连接到数据库的代码时,如何使用这些信息

目前(只有GlassFish安装,没有JDBC配置),我依靠CentOS java环境变量(如CLASSPATH)来允许web应用程序使用JDBC驱动程序。但是,我得到了以下错误:

java.lang.NoClassDefFoundError: oracle/jdbc/pool/OracleDataSource 
java.lang.ClassCastException : com.sun.gjc.spi.jdbc40.DataSource40 cannot be cast to oracle.jdbc.pool.OracleDataSource
因此,我尝试在GlassFish中创建JDBC连接池和资源(这样应用程序就可以使用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...
我得到了错误:

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:我用下面cyril的评论清除了那些编译错误(抛出所有异常)。然后我创建了JDBC连接池和JDBC资源,Ping成功了。因此,我从客户端运行应用程序并观察到以下错误:

java.lang.NoClassDefFoundError: oracle/jdbc/pool/OracleDataSource 
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 ds = (OracleDataSource)ctext.lookup("jdbc/myDBPool");
DataSource ds = (DataSource)ctext.lookup("jdbc/myDBPool");

它编译时没有错误。但是现在我很困惑。。。我们不是应该在这里使用OracleDataSource吗?或者,GlassFish是否以某种方式实现了OracleDataSource,因为我确实看到
Datasource Classname
的连接池设置为
oracle.jdbc.pool.OracleDataSource
(?)。希望有人能解释这一点。

对连接池执行ping操作吗? 如果没有,请检查您的池配置w/

Ping工作并配置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可能抛出的已检查异常。 出于测试目的,解决此问题(以及类似于此的未来错误)的最简单方法是扩大方法签名以抛出所有异常,即:

public static void main(String args[]) throws /*SQL*/Exception {
对更新2的答复:
除非您需要访问JDBC规范中未指定的任何自定义功能,否则没有理由将JDBC接口强制转换为Oracle实现。数据源的目的是作为连接工厂,其API在JDBC接口中定义,因此您只需要这些。当您在GlassFish中定义连接池和资源时,只要您坚持导入java.sql.*,应用服务器就会通过包装JDBC驱动程序类并为您无缝代理它们来增加价值。不需要oracle导入:)主要的优点是,如果您以后决定切换到MySQL或其他数据存储,那么您的代码是可移植的,不需要任何更改

要补充cyril的好答案:

您也可以使用资源注入来设置
数据源,而不是JNDI查找:

@Resource(name = "jdbc/Your_DB_Res")
private DataSource ds;
启动时,应用服务器将注入JDBC资源。JavaEE教程的作者对此有更多的论述


通过使用资源注入,您可以减少样板代码的数量。介绍这些概念。

除了将驱动程序添加到类路径之外,还应该尝试将appserv-rt.jar文件添加到项目的构建路径中(jar位于Glassfish的lib目录中)。如果您不想包含所有其他jar,您应该首先创建一个包含appserv rt jar的库,然后将其添加到项目的构建路径中。

出现此错误的原因是您没有部署JDBC驱动程序,JDBC驱动程序也不是容器类路径的一部分。无论如何,使用JNDI是一个更好的主意,但是如果不部署JDBC驱动程序,它不会神奇地允许您使用它。感谢更新1响应。有了你的推荐,它现在编译得很好。谢谢你,西里尔!请参阅上面的更新2。谢谢。一种方法比另一种方法有什么重要的优点或缺点吗?@ggkmath在我的回答中添加了一个资源注入简介的链接。