第一次用Java連接讀取MySQL實現登陸校驗功能過程中自己犯的一些錯誤的總結

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
	request.setCharacterEncoding("utf-8");//不加網頁會亂碼
		String URL = "jdbc:mysql://localhost:3306/student";//主機號,端口號,要連的數據庫名稱
		String USENAME = "root";//用戶名
		String PWD = "123";//密碼

		Connection connection = null;
		Statement pstmt = null;//提升作用域
		try {
			// 導入驅動,加載具體的驅動類
			Class.forName("com.mysql.jdbc.Driver");
			// 與數據庫建立連接
			connection = DriverManager.getConnection(URL, USENAME, PWD);//ctrl+1返回對象
			//發送sql(執行增刪改,查)
			String name=request.getParameter("uname");//uanme
			String pwd=request.getParameter("upwd");
			
			/* String sql="select * from `check` where name=? and pwd=?";
			pstmt = connection.prepareStatement(sql);//jsp裏面不能用父類,只能寫具體類,繼承好像用不了
			pstmt.setString(1, "'"+name+"'");
			pstmt.setString(2, "'"+pwd+"'"); */
			pstmt=connection.createStatement();
			String sql="select * from `check` where name='"+name+"' and pwd='"+pwd+"'";
			ResultSet rs=pstmt.executeQuery(sql);
			//out.print(rs.next()+""+rs.getString(1));
			if(rs.next())
				out.print("登陸成功!");
			else
				out.print("失敗");
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {//以防萬一,加個總異常(如果出現了除上述兩個異常之外的異常)
			e.printStackTrace();
		} finally {//不管上面執行與否該句必然執行
			try {
				//				stmt.close();connection.close();
				if (pstmt != null)
					pstmt.close();//防止java.lang.NullPointerException
				if (connection != null)
					connection.close();//java.lang.NullPointerException
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	%>
</body>
</html>

實現個登陸功能還真不是那麼容易,要注意的細節很多,這裏我來逐一記錄一下我犯的一些錯誤!

1.

String sql="select * from `check` where name='"+name+"' and pwd='"+pwd+"'";

我在數據庫裏面建了一個叫check的表,用上面這個sql語句執行,結果報了下面這個錯誤

一直找不到錯,然後我在MySql裏面執行搜索語句,也報了這個錯

後來猛然注意到check怎麼也是藍色的,這說明它是系統保留字,不能私自亂用的,如果一定要用可以 加` `括起來(不是' ',是esc鍵下面那個按鍵),但是問題並沒有完全解決,我的name字段是varchar類型,所以sql語句裏要加‘’號(不要忘記,

where name=' "+name+" ')。

2.

String sql="select count(*) from `check` where name='"+name+"' and pwd='"+pwd+"'";

其他不變,把* 改爲count(*),結果恆成立,就是不管輸入什麼都會顯示登陸成功!爲什麼會這樣呢?這裏其實所有的語法邏輯都沒問題,你用eclipse調試到死都找不到錯,很糾結,然後把sql語句放MySQL一試就明白了

不存在的顯示爲

 

也就是說返回的ResultSet必然有一條記錄(0也算一條記錄),如此第一次next()函數必然返回true,結果恆成立。

3.

這個錯誤真的找了很久,一開始沒意識到next()其實就跟指針的概念一樣,導致結果就是顯示失敗,因爲我的ResultSet裏面就一條記錄,out.print(rs.next())後再一次調用rs.next()時其實已經找不到下一條記錄了,所以返回false;

4.

還有一點要注意的是用Statement會有被sql注入的風險,比如我密碼用 hxjhdsb ' or'1=1,實際Java用字符串拼接後發給MySQL執行的sql語句如下,前面的條件不管真假都被無視,後面的‘1=1’恆成立,結果恆爲真,就select了所有數據:

爲了安全,改用PreparedStatement就行了,關鍵代碼如下:

                  String sql="select * from `check` where name=? and pwd=?";
			pstmt = connection.prepareStatement(sql);//jsp裏面不能用父類,只能寫具體類,繼承好像用不了
			pstmt.setString(1,name);
			pstmt.setString(2, pwd); 
			ResultSet rs=pstmt.executeQuery();
			/* pstmt=connection.createStatement();
			String sql="select * from `check` where name='"+name+"' and pwd='"+pwd+"'";
			ResultSet rs=pstmt.executeQuery(sql);
			out.print(rs.next()); */
			if(rs.next())
				out.print("登陸成功!");
			else
				out.print("失敗");

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章