2017-05-01 120 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(); 
}