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