1. 程式人生 > >使用Map集合,PreparedStatement 介面對 MySQL 語句中的?佔位符進行設定

使用Map集合,PreparedStatement 介面對 MySQL 語句中的?佔位符進行設定

使用?佔位符的原因: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用在商業專案上。
注:-- 是資料庫註釋