<%@ 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("失敗");