占位符的使用
Statement 接口的兩個問題:
第一個問題: 使用 Statement 接口 對象發送的 sql 語句需要再數據庫進行一次編譯之后成為指令才能執行,
每條 sql 語句都需要編譯一次, 這樣是很慢的.
第二個問題: 使用 Statement 接口 操作的 sql 語句需要使用字符串的拼接方式實現,
這樣的方式可能存在 sql 注入的安全風險並且拼接字符串比較麻煩.
對比 Statement 接口, PreparedStatement 接口的優點:
1.使用該接口操作的 sql 語句會先預先編譯成指令在發送給數據庫, 數據庫就執行指令即可, 這樣就提高了一定速度,
2.該接口可以避開 sql 需要使用字符串拼接的方式, 從而解決 sql 注入的安全風險,
而是使用 占位符 (?) 來代替原來的字符串拼接.
Demo:實現無密碼登錄
不使用 sql 字符串拼接, 而是使用占位符來實現
1 public class TestMysql1 { 2 //取得連接 3 private static Connection conn =ConnectionUitl.getConnection(); 4 5 public static void main(String[] args) { 6 selectLogin("smith","1234"); 7 } 8 /** 9 * 實現登錄 10 * @param name 用戶名 11 * @param password 密碼 12 * @return 13 */ 14 public static boolean selectLogin(String name, String password) { 15 String sql = "SELECT * FROM myuser WHERE username=? AND password=?"; 16 System.out.println(sql); 17 18 try { 19 PreparedStatement pst = conn.prepareStatement(sql); 20 //為占位符設置具體內容 21 pst.setString(1, name); 22 pst.setString(2, password); 23 //發送 sql 語句 24 ResultSet rst = pst.executeQuery(); 25 if (rst.next()) { 26 System.out.println("登錄成功!"); 27 } else { 28 System.out.println("用戶名或密碼錯誤!"); 29 } 30 } catch (SQLException e) { 31 e.printStackTrace(); 32 } 33 return false; 34 } 35 }
Demo: 插入數據 (使用占位符)
1 public class TestMysql2 { 2 //取得連接 3 private static Connection conn =ConnectionUitl.getConnection(); 4 5 public static void main(String[] args) { 6 Emp emp = new Emp(); 7 emp.setEmpno(1009); 8 emp.setEname("李四"); 9 emp.setJob("職員"); 10 emp.setMgr(8965); 11 emp.setSal(10.00); 12 emp.setComm(900.0); 13 emp.setHiredate(new Date()); 14 emp.setDeptno(40); 15 System.out.println(insertEmp(emp)); 16 } 17 /** 18 * 插入雇員信息的方法 19 * @return 20 */ 21 public static int insertEmp(Emp emp) { 22 //定義出 sql 語句 23 String sql = "INSERT INTO emp(empno,ename,job,sal,hiredate,mgr,comm,deptno)" 24 +" VALUES(?,?,?,?,?,?,?,?)"; 25 26 try { 27 //使用連接對象取得發送 sql 語句的對象 (PreparedStatement 接口對象) 28 PreparedStatement pst = conn.prepareStatement(sql); 29 //設置占位符的內容 30 pst.setInt(1, emp.getEmpno()); 31 pst.setString(2,emp.getEname()); 32 pst.setString(3,emp.getJob()); 33 pst.setDouble(4,emp.getSal()); 34 pst.setDate(5,new java.sql.Date(emp.getHiredate().getTime())); 35 pst.setInt(6,emp.getMgr()); 36 pst.setDouble(7,emp.getComm()); 37 pst.setInt(8,emp.getDeptno()); 38 //執行 sql 語句 39 return pst.executeUpdate(); 40 } catch (SQLException e) { 41 e.printStackTrace(); 42 } finally { 43 ConnectionUitl.close(conn); 44 } 45 return 0; 46 } 47 }