2012-02-26 71 views
1

我是JDBC新手。我在Centos 6.2上安裝了GlassFish 3.1.1,需要將它與連接到另一臺服務器上的Oracle 11G數據庫的應用程序一起使用。我已閱讀GlassFish的文檔,並認爲我瞭解如何創建JDBC連接池以及JDBC資源。我的問題是,如何在編寫java中間層連接到數據庫時使用這些信息?在GlassFish中創建JDBC連接池後,如何使用JDBC更改Java代碼以訪問數據庫?

目前(僅使用GlassFish安裝而沒有JDBC配置),我依靠Java的CentOS環境變量(例如CLASSPATH)來允許Web應用程序使用JDBC驅動程序。不過,我發現了以下錯誤:

java.lang.NoClassDefFoundError: 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/[email protected]: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 webserver JDK 1.6。我沒有任何集羣或負載平衡。

更新1:我認爲this link是一個很好的參考(請參見標題爲「創建數據源實例,註冊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/[email protected]: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:我清除那些使用下面的cyril的註釋編譯錯誤(拋出所有例外)。然後我創建了JDBC連接池和JDBC資源,並且Ping成功。於是我從客戶端運行的應用程序,並遵守下列錯誤:

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"); 

成爲本line:

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

它編譯沒有錯誤。但是現在我感到困惑......我們是不是應該在這裏使用OracleDataSource?或者,GlassFish以某種方式實現OracleDataSource,因爲我看到Datasource Classname設置爲oracle.jdbc.pool.OracleDataSource(?)的連接池的設置。希望有人能解釋這一點。

+0

您得到該錯誤的原因是因爲您沒有部署JDBC驅動程序,JDBC驅動程序也不是容器類路徑的一部分。無論如何,使用JNDI是一個更好的主意,但如果不部署它,它並不會讓你使用JDBC驅動程序。 – 2012-02-26 23:44:55

回答

2

在連接池中工作嗎? 如果沒有,請檢查您的池配置W/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引發的檢查異常。 出於測試目的,出了這一點(和喜歡這個未來的錯誤),最簡單的方法是隻擴大你的方法簽名拋出所有的異常,即:

public static void main(String args[]) throws /*SQL*/Exception { 

響應更新2: 沒有理由投除非需要訪問JDBC規範中未指定的任何自定義功能,否則JDBC可以與Oracle實現接口。 DataSource的目的是成爲Connections的工廠,其API是在JDBC接口中定義的,因此應該是您所需要的。當您在GlassFish中定義連接池和資源時,只要您堅持導入java.sql。*,應用程序服務器就會通過包裝JDBC驅動程序類併爲您無縫地代理它們來添加值。不需要oracle導入:)主要優點是,如果您以後決定切換到MySQL或其他數據存儲,那麼您的代碼便可以隨身攜帶,不需要任何更改。

+0

感謝您的更新1迴應。根據您的建議,現在編譯好。謝謝你cyril!請參閱上面的更新2。 – ggkmath 2012-02-27 02:47:09

1

爲了增加西里爾很好的答案:

代替JNDI查找,您還可以使用資源注射設置您DataSource

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

在啓動時,應用程序服務器將注入JDBC資源。 Java EE Tutorial的This section有更多關於此事的信息。

通過使用資源注入,可以減少樣板代碼的數量。 This article介紹了這些概念。

+0

謝謝TPete。是否有任何重要的優點或缺點以一種方式比另一種方式? – ggkmath 2012-02-27 14:01:27

+0

@ggkmath編輯我的答案,並附上資源注入簡介。 – TPete 2012-02-27 14:53:02

0

除了將驅動程序添加到類路徑之外,還應該嘗試將appserv-rt.jar文件添加到項目的構建路徑(該jar位於Glassfish的lib目錄中)。如果您不想包含所有其他jar,則應首先創建一個包含appserv-rt jar的庫,然後將其添加到項目的構建路徑中。