使用Map集合,PreparedStatement 介面對 MySQL 語句中的?佔位符進行設定
阿新 • • 發佈:2019-01-07
使用?佔位符的原因:Statement不安全,存在SQL注入防風險!
涉及知識點:Map集合,PreparedStatement 介面,MySQL資料庫,ResultSet結果集
使用方法:
博主是用的是 eclipse Jee IDE,使用MySQL需要在
.....\工程名\WebContent\WEB-INF\lib
中放入mysql資料庫驅動檔案,mysql-connector-java-5.1.21.jar
長這個樣子,1M左右的大小
Jsp檔案form表單中傳送使用者名稱和密碼,通過Servlet獲取並在資料庫中進行查詢,如果資料庫中不存在,則提示“使用者名稱密碼輸入有誤”,並轉發到登入介面,如果存在,則進入到mainpage.jap中。
以下是Servlet檔案中的doPost()方法中的程式碼
String username=request.getParameter("username"); String password=request.getParameter("password"); boolean flag=false; DBUtil db = new DBUtil(); //引入 資料庫工具類 物件 String sql="select count(*) from user where username=? and password=?"; Map<Integer,Object> param =new HashMap<Integer,Object>(); param.put(1,username); param.put(2,password); ResultSet rs = db.eQuery(sql, param);//獲取返回的結果集rs try { if(rs!=null && rs.next()) { int count =rs.getInt(1); //獲取欄位1的數量,如果有記錄則為1,沒有則為0 if(count>0) { flag=true; } } } catch (SQLException e) { e.printStackTrace(); } finally { db.closeSql(); } if(flag) { //如果資料庫中存在該賬號密碼 //在Servlet中使用session必須先得到session物件 //而JSP中session是內建物件之下,不用建立就可以直接使用 //使用session域傳值,session在網頁中一直存在,可以直接用request從介面中獲取 //向Session中存取登入資訊 HttpSession session = request.getSession(); session.setAttribute("username",username); response.sendRedirect("mainpage.jsp"); //重定向到主介面 } else { request.setAttribute("msg","使用者名稱密碼輸入有誤!"); //失敗,轉發到登入介面繼續進行登入 request.getRequestDispatcher("login.jsp").forward(request, response); } }
以下是資料庫執行 DBUtil.java 檔案中的程式碼
匯入標頭檔案
import java.sql.*;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.sql.Connection;
首先註冊並連結MySQL資料庫
// 定義JDBC連線Mysql 5 private static final String DRIVER = "com.mysql.jdbc.Driver"; //定義所使用資料庫的 主機號 埠號 資料庫名 private static final String URL = "jdbc:mysql://localhost:3306/資料庫名"; //定義所用資料庫的 使用者名稱 和 密碼 private static final String USERNAME = "使用者名稱"; private static final String PASSWORD = "密碼"; //公共元素 int num = 0; //返回所需查詢結果的個數 Connection conn = null; //建立連線 ResultSet rs = null; //sql查詢結果儲存在結果集中 PreparedStatement ps = null; // //在預設構造方法中註冊驅動,獲取資料庫連線 public DBUtil() { try { Class.forName(DRIVER); //註冊驅動 //獲取資料庫的連線 conn = DriverManager.getConnection(URL, USERNAME, PASSWORD); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } }
實現查詢方法
//返回一個結果集
public ResultSet eQuery(String sql,Map<Integer,Object> param) {
try {
ps = conn.prepareStatement(sql);
//用迴圈給?佔位符賦值
//Map有兩個集合,一個是值的集合,用 Map介面物件.keySet()獲取,一個是鍵的集合,用 介面物件.values()獲取
for(Integer key : param.keySet()) { //獲取Map中key的集合
Object value = param.get(key); //獲取key對應的value值
ps.setObject(key, value);
}
rs = ps.executeQuery(); //返回一個結果集rs
}
catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
實現增刪改方法
//返回受影響的記錄條數 是一個整數
public int eUpdate(String sql,Map<Integer,Object> param) {
try {
ps = conn.prepareStatement(sql);
for(Integer key : param.keySet()) {
Object value = param.get(key);
ps.setObject(key,value);
}
num = ps.executeUpdate(); //返回受影響的記錄條數
}
catch (SQLException e) {
e.printStackTrace();
}
return num;
}
關閉資料庫連線
public void closeSql() {
try {
if(ps != null) {
ps.close();
}
if(rs != null) {
rs.close();
}
if(conn != null) {
conn.close();
}
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
JDBC流程:
//
//第一步:載入Driver類,註冊資料庫驅動;
//第二步:通過DriverManager,使用URL、使用者名稱、密碼去建立連線(Connection);
//
//第三步:通過Connection,使用sql語句開啟Statement、PreparedStatement物件;
//
//第四步:執行ps.executeQuery() 或 ps.executeUpdate() 語句,將結果返回 ResultSet;
//
//第五步:對結果ResultSet進行處理;
//
//第六步:倒敘釋放資源ResultSet-》PreparedStatement-》Connection。
使用PreparedStatement 介面設定?佔位符的原因:如使用Statement執行sql語句,在登陸的時候,使用者名稱使用
' or 1=1 --
時,會成功登入,這是很大的漏洞,同樣的,在輸入框也可以寫一些極具危險性的sql語句!所以不建議使用Statement用在商業專案上。
注:-- 是資料庫註釋