2017-05-01 113 views
0

嗨,我想在java中使用Access數據庫,我有一個麻煩點。下面我已經建立了一個連接到我的數據庫。java訪問嘗試代碼塊從一個單獨的類

public class DBAccess { 
DBAccess() { 
    try { 
     Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
     String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=CFPDB.mdb;"; 
     Connection conn = DriverManager.getConnection(database, "", ""); 
     Statement s = conn.createStatement(); 
    } 
    catch(Exception ex) { 
     ex.printStackTrace(); 
    } 
} 
} 

我需要我的GUI類來訪問的「變量的形式,以檢查密碼:

else if(event.getSource() == loginSubmitButton){ 
     DBAccess loginCheck; 
     String selFromTable = "SELECT PASSWORD FROM USERS WHERE USERNAME = '" + loginUsername.getText() + "'; "; 
     loginCheck.s.execute(selFromTable); 
     ResultSet retrievedPassword = loginCheck.s.getResultSet(); 
     String password = retrievedPassword.getString(1); 
     String password_entered = loginPassword.getText(); 
    } 

但我的編譯器說,它無法找到符號 - 可變的' 。 DBAccess類與我的gui在一個單獨的文件中,但都在同一個包中。任何幫助都會很棒。 :)

+0

要讓類份額事情,我們有一流的領域和getter世界。 – Pshemo

+1

's'不是一個字段,只要對象被創建,它就是一個超出範圍的變量。另一個問題是該對象從不創建,並且永遠不會清理SQL,從而使您容易受到SQL注入的攻擊。 – Compass

回答

0

Java不喜歡這個工作,每個變量都有自己的範圍,說明在哪裏它定義了哪裏容易被使用,什麼時候被垃圾收集器收集。一般來說,在開始時記住它的一個好方法是變量只能在最近的括號內「生存」。

在這種情況下,你的'''變量對try-catch塊的範圍有限,所以一旦該塊結束,s變量不再可用,你可以通過編譯這段代碼來驗證:

DBAccess() { 
    try { 
     Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
     String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=CFPDB.mdb;"; 
     Connection conn = DriverManager.getConnection(database, "", ""); 
     Statement s = conn.createStatement(); 
     s.execute(""); // compiles without problem. 
    } 
    catch(Exception ex) { 
     s.execute(""); // does not compile. 
     ex.printStackTrace(); 
    } 
    s.execute(""); // does not compile. 
} 

所以,你最好的選擇就是宣告S作爲一類領域:

public class DBAccess { 

    private Statement s; 

    DBAccess() { 
     try { 
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
      String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=CFPDB.mdb;"; 
      Connection conn = DriverManager.getConnection(database, "", ""); 
      s = conn.createStatement(); 
     } 
     catch(Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    public Statement getStatement() { 
     return s; 
    } 
} 

然後訪問它通過它的getter方法。順便說一句,記得通過其構造函數(2號線)

else if(event.getSource() == loginSubmitButton){ 
     DBAccess loginCheck = new DBAccess(); // invoke constructor 
     String selFromTable = "SELECT PASSWORD FROM USERS WHERE USERNAME = '" + loginUsername.getText() + "'; "; 
     loginCheck.getStatement().execute(selFromTable); 
     ResultSet retrievedPassword = loginCheck.getStatement().getResultSet(); 
     String password = retrievedPassword.getString(1); 
     String password_entered = loginPassword.getText(); 
} 

另一種選擇,我真的不建議(但狀態這裏只是讓你知道)是聲明的能量場作爲公共實例化你的對象:

public class DBAccess { 

    public Statement s; 

    DBAccess() { 
     try { 
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
      String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=CFPDB.mdb;"; 
      Connection conn = DriverManager.getConnection(database, "", ""); 
      s = conn.createStatement(); 
     } 
     catch(Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

然後你就可以訪問你想要的方式:

loginCheck.s.execute(selFromTable); 
+0

雖然MatějRačinský的回答也是正確的SEAang's更簡潔,並且寫有解釋以幫助未來觀衆這個問題。順便拜託你們倆:) –

0

您需要從s創建字段,因爲字段存在,只要擁有它的對象存在。當DBAccess構造函數完成時,s現在消失。使用getter

public class DBAccess { 

private Statement s; 

DBAccess() { 
    try { 
     Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
     String database = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=CFPDB.mdb;"; 
     Connection conn = DriverManager.getConnection(database, "", ""); 
     s = conn.createStatement(); 
    } 
    catch(Exception ex) { 
     ex.printStackTrace(); 
    } 
} 

public Statement getStatement() { 
    return s; 
} 
} 

,並在你的GUI類訪問S:所以,你想是這樣的

else if(event.getSource() == loginSubmitButton){ 
    DBAccess loginCheck; 
    String selFromTable = "SELECT PASSWORD FROM USERS WHERE USERNAME = '" + loginUsername.getText() + "'; "; //this is vulnerable to SQL injection, use prepared statements, see for example, here https://www.mkyong.com/jdbc/jdbc-preparestatement-example-select-list-of-the-records/ 
    loginCheck.getStatement().execute(selFromTable); 
    ResultSet retrievedPassword = loginCheck.s.getResultSet(); 
    String password = retrievedPassword.getString(1); 
    String password_entered = loginPassword.getText(); 
}