2017-11-25 301 views
0

我正在學習Java JDBC,並且正在使用循環將數據存儲到數據庫(mySQL db)中。 當我存儲第一名稱和個人的姓氏,它似乎工作正常,但是當我嘗試插入電子郵件地址,我得到以下錯誤:將數據插入數據庫Java JDBC

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@123.com)'

據我所知,除非我錯過了一些不可思議的東西,我看不出有什麼語法錯誤?

我的代碼如下:

import java.sql.*; 
import java.util.ArrayList; 
import java.util.Arrays; 

public class Driver { 
    public static void main(String[] args) { 
     try{ 
      Connection myConn = DriverManager.getConnection("jdbc:mysql://localhost:8889/demo","root","root"); 
      Statement myStmt = myConn.createStatement(); 
      ArrayList<String> firstNames = new ArrayList<String>(Arrays.asList("James", "John","Mark")); 
      ArrayList<String> lastNames = new ArrayList<String>(Arrays.asList("Handly", "licks","manford")); 
      ArrayList<String> emails = new ArrayList<String>(Arrays.asList("[email protected]", "[email protected]","[email protected]")); 

      for (int i = 0; i < firstNames.size(); i++){ 
       String sql = "INSERT INTO EMPLOYEES (first_name,last_name,email) VALUES (" + firstNames.get(i)+ ", " + lastNames.get(i) + ", " + emails.get(i) + ");"; 
       myStmt.executeUpdate(sql); 
      } 
      ResultSet myRes = myStmt.executeQuery("select * from Employees"); 
      while(myRes.next()){ 
       System.out.println(myRes.getString("first_name")+", "+ myRes.getString("last_name")); 
      } 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

當我試圖在一個時間例如插入數據的一個

String sql = "INSERT INTO EMPLOYEES (first_name,last_name,email) VALUES ('John','test','[email protected]')"; 
myStmt.executeUpdate(sql); 

這工作正常,所以我很困惑,爲什麼數據沒有正確傳遞。 謝謝!

編輯: 承蒙@scaisEdge和@ A.A反饋,儘管我一直在尋找做工作,用字符串文本的修補程序是一個BAD主意,因爲這打開了SQL注入。 反過來,我現在修改了我的代碼,使用Prepared語句(@ A.A的答案),它已經工作了,並且問題少得多!

新的代碼如下:

import java.sql.*; 
import java.util.ArrayList; 
import java.util.Arrays; 

public class Driver { 
    public static void main(String[] args) { 

     Connection myConn = null; 
     PreparedStatement myStmt = null; 
     ResultSet myRs = null; 
     try{ 
      //1.get connection to db 
      myConn = DriverManager.getConnection("jdbc:mysql://localhost:8889/demo","root","root"); 

      ArrayList<String> firstNames = new ArrayList<String>(Arrays.asList("James", "John","Mark")); 
      ArrayList<String> lastNames = new ArrayList<String>(Arrays.asList("Handly", "licks","manford")); 
      ArrayList<String> emails = new ArrayList<String>(Arrays.asList("[email protected]", "[email protected]","[email protected]")); 
      for (int i = 0; i < firstNames.size(); i++){ 

       //Insert Query 
       myStmt = myConn.prepareStatement("INSERT INTO EMPLOYEES (first_name,last_name,email) VALUES (?,?,?)"); 

       myStmt.setString(1,firstNames.get(i)); 
       myStmt.setString(2,lastNames.get(i)); 
       myStmt.setString(3,emails.get(i)); 
       myStmt.execute(); 
      } 
      ResultSet myRes = myStmt.executeQuery("select * from Employees"); 
      while(myRes.next()){ 
       System.out.println(myRes.getString("first_name")+", "+ myRes.getString("last_name")); 
      } 
      myConn.close(); 
     }catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+3

您跳過字符串單引號值 – rpc1

+0

利用PreparedStatement(https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html)至像這樣的狂熱問題。它會自動爲您添加引號並轉義可能導致語句失效的事物。 – Pshemo

+0

我剛剛在該文檔頁面中偶然發現,同時尋找答案並準備嘗試下一步:)謝謝! –

回答

5

我也建議使用準備好的語句,它不僅是更具可讀性,也可以防止你的SQL注入攻擊。更多信息here

例子:

preparedStatement = connection.prepareStatement("INSERT INTO EMPLOYEES (fname, lname, email) VALUES (?, ?, ?)"); 
preparedStatement.setString(1, person.getFName()); 
preparedStatement.setString(2, person.getLName()); 
preparedStatement.setString(2, person.getEmail());