2016-12-23 41 views
0

最近我在用Python大量時間後回到了Java,並且我試圖再次適應它。我的第一個期望的項目是創建一個小應用程序,您可以(首先)登錄。我正在使用mySQL來保存用戶名和密碼數據庫。如何從其他類或方法「提取」變量?

到目前爲止,我已經使用Java的swing GUI來創建彈出框,要求登錄信息。輸入的用戶名和密碼將針對SQL表中的用戶名和密碼進行測試。

問題是我正在使用while循環來測試對SQL表的輸入。因此,輸入的信息將根據SQL表創建的Hashmap中的每個鍵和值進行檢查。

我不確定如何從while循環和SQL的try語句中「提取」我的變量g(Hashmap),以便在用mySQL中的數據填充後可以使用它。

我使用Eclipse(Java Neon)。我不知道如何「提取」哈希映射,當我嘗試讓while循環或try語句返回哈希映射時,Eclipse會通知我void方法不能返回值(顯然)。但是,我無法將返回類型從void更改爲HashMap)String,String>因爲「返回類型與ActionListener.actionPerformed(ActionEvent e)不兼容」和「implements java.awt.event.ActionListener.actionPerformed」。

這裏是我的代碼:

import javax.swing.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.util.HashMap; 
import java.util.Map; 

public class Hello0 extends JFrame { 
    private static final long serialVersionUID = 1487932324102279819L; 

    public static void main(String[] args) { 
     JFrame frame = new JFrame("Frame Demo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(350, 200); 

     JPanel panel = new JPanel(); 
     frame.add(panel); 
     placeComponents(panel); 

     frame.setVisible(true); 
    } 


    private static void placeComponents(JPanel panel) { 

     panel.setLayout(null); 
     JLabel userLabel = new JLabel("Username"); 
     userLabel.setBounds(10, 20, 80, 25); 
     panel.add(userLabel); 

     JTextField userText = new JTextField(20); 
     userText.setBounds(100, 20, 165, 25); 
     panel.add(userText); 

     JLabel passwordLabel = new JLabel("Password"); 
     passwordLabel.setBounds(10, 50, 80, 25); 
     panel.add(passwordLabel); 

     JPasswordField passwordText = new JPasswordField(20); 
     passwordText.setBounds(100, 50, 165, 25); 
     panel.add(passwordText); 

     JButton loginB = new JButton("Login"); 
     loginB.setBounds(10, 80, 80, 25); 
     panel.add(loginB); 

     loginB.addActionListener(new ActionListener() { 

      public HashMap<String, String> actionPerformed(ActionEvent e) { 
       String username0 = "root"; 
       String password = "javaSQLmy98"; 
       try { 

        String url = "jdbc:mysql://localhost:3306/javabase?useSSL=false"; 
        Connection connection = DriverManager.getConnection(url, username0, password); 
        PreparedStatement stmt0 = connection.prepareStatement("SELECT * from userids"); 

        String pass0 = null; 
        String user1 = userText.getText().toString(); 
        char[] pass1 = passwordText.getPassword(); 
        pass0 = String.valueOf(pass1); 
        System.out.println(user1); 
        System.out.println(pass1); 

        ResultSet rs = stmt0.executeQuery(); 
        rs = stmt0.executeQuery("SELECT * from userids "); 
        while (rs.next()) { 

         String user = rs.getString("username"); 
         String pass = rs.getString("paswrd"); 

         Map<String, String> g = new HashMap<>(); 
         g.put(user, pass); 
         return g; 
         // This was the alternative: if(g.keySet().contains("Jacob") && g.values().contains("root")) { 


         /*This code below was originally outside the while loop but I could not 
         figure out how to make it work without it being inside, and accessible 
         to the hashmap g. Now it is being checked each time the while loop 
         is ran, with a new pair of usernames and passwords on each loop. */ 

         if (user1.equals(user) && pass0.equals(pass)) { 
          System.out.println("Good!"); 
         } 

         /*The problem here is that the checker IS inside the loop, so it 
         tests the input against each of the entries in the SQL table. */ 
         else { 
          System.err.println("The username or password is incorrect."); 
         } 
        } 

        connection.close(); 
       } catch (Exception e1) { 
        System.err.println(e1.getMessage()); 
       } 

      } 
     }); 

    } 

} 

乾杯!

+0

爲什麼您將所有內容加載到HashMap中,而不是在SQL查詢中只包含WHERE子句? –

+0

您是否瞭解如何在SQL中編寫查詢以獲取用戶標識的單個行,而不是遍歷表中的所有行? –

+0

@RiaanNel我不知道這將如何幫助。 WHERE關鍵字不只是充當過濾器嗎? –

回答

0

如果向查詢添加WHERE子句,它將僅返回符合條件的數據。換句話說,下面的查詢(顯然具有正確的值)將返回指定的userid條目,如果它存在,否則它將返回一個空的結果集。

SELECT * from userids 
WHERE userName = 'user1' 
AND passwrd = 'pass1' 

然後,您可以與整個廢除while循環和HashMap和代碼可以簡化爲如下:

if (rs.next()) { 
    System.out.println("Good!"); 
} else { 
    System.err.println("The username or password is incorrect."); 
} 

此外,如前所說,如果這是什麼比一個更編程練習時,密碼應該散列而不是以純文本形式存儲。

+0

這對特定值「user1」和「pass1」很有用,但我將如何使用用戶名和密碼輸入? –

+0

沿着「SELECT ...」+用戶+「AND ...」+ pass(這很糟糕,因爲這會讓您容易受到SQL注入攻擊),或者您可以使用PreparedStatement(更好的選擇)。 http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html –

+0

你有解決你的問題嗎?如果是這樣,請將答案標記爲已接受。 http://stackoverflow.com/help/someone-answers –

1

要訪問gwhile的,你需要聲明它while之外,如Java中的每個{}作用域它裏面的變量。因此,

Map<String, String> g = new HashMap<>(); 
while (condition) { 
    // do something 
    g.put(key, value); 
} 
// do something with g 

但在這種情況下,您可以直接在SQL中執行檢查,這應該更有效。


旁註:

不要將密碼存放。 Don't store passwords.Hash+Salt passwords (or better, use a library).

+0

謝謝你的回答和建議。在while循環之外聲明它會創建一個空的Hashmap呢?然後我將它填充到while循環中,但現在可以在外部使用它,因爲它聲明的位置? –

+0

@JacobAdamczyk究竟是 – CAD97

0

試試這個:

Map<String, String> g = new HashMap<String, String>(); 
while(rs.next()) { 
    String user = rs.getString("username"); 
    String pass = rs.getString("paswrd"); 
    g.put(user, pass); 

    ..... 
} 

注:以用戶名作爲HasmMap的關鍵是不是一個很好的編程,因爲可以有多個用戶使用相同的名稱。

+0

你會推薦什麼其他的數據結構呢? –

+0

這取決於您當前的要求。你可以有一個設置或如果你想要與地圖,那麼你可以去與地圖。其中key將是long類型的用戶標識,值將是POJO類。 – SujitKumar

+0

上面的POJO類將具有像userId,userName,密碼等屬性。 – SujitKumar

相關問題