第一次用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("失败");

 

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