使用?占位符的原因: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 param =new HashMap();
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 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 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用在商业项目上。
注:-- 是数据库注释