Java-JDBC-PreparedStatement和SQL注入
目录
内容
1、登录案例
-
需求:输入用户名和密码,如果用户名和密码同数据库中存储的用户名和密码相同,则运行登录,否则不允许登录
-
步骤:
-
创建login表
-
username字段
-
password字段
create table login( id int primary key auto_increment, username varchar(20) not null, password varchar(100) not null );
-
-
插入测试数据
insert into login(username, password) values ('zhangsan', 'a123'), ('lishi', '3f2f3');
-
图示1-1:
-
编写登录逻辑
package cn.gaogzhen.jdbc; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Scanner; import cn.gaogzhen.domain.Emp; import cn.gaogzhen.util.JDBCUtils; public class JDBCDemo7 { public static void main(String[] args) throws SQLException { Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String username = sc.nextLine().trim(); System.out.println("请输入密码:"); String password = sc.nextLine().trim(); String res = login(username, password)? "登录成功": "登录失败"; System.out.println(res); } public static boolean login(String username, String password) throws SQLException { if(username == null || password == null) return false; Connection conn = JDBCUtils.getConnection(); String sql = "select * from login where username = '" + username +"' and password = '" + password + "'"; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); boolean flag = rs.next(); JDBCUtils.close(rs, stmt, conn); return flag; } }
-
测试结果:
// 成功 请输入用户名: zhangsan 请输入密码: a123 登录成功 // 失败 请输入用户名: fewf 请输入密码: fwfe 登录失败
-
-
注意:JDBCUtils类为上一篇JDBCUtils工具类博文中编写的工具类
2、SQL注入
在#1登录案例中,如何密码输入
as' or '1' = '1#
用户名随意,试一下会发生什么?
测试结果:
请输入用户名:
fasdfa
请输入密码:
sfas' or '1'='1
登录成功
这就是SQL注入问题,关于SQL注入的详情,有兴趣的小伙伴可自行查阅相关文档。那么这里怎么解决SQL注入问题呢?这就是需要用到下面要介绍的PreparedStatement对象。
3、PreparedStatement
- 表示预编译的SQL语句的对象:用?代替参数
- 步骤
- 导入jar包:mysql-connector-java-版本号-bin.jar
- 注册驱动
- 获取连接对象Connection
- sql语句
- 注意:sql语句的参数使用?作为占位符,如select * from login where username = ? and password = ?
- 获取执行sql语句的对象PreparedStatement
- 给?赋值
- 方法:setXXX(参数1, 参数2)
- 参数1:?的位置编号,从1开始
- 参数2:?的值
- 方法:setXXX(参数1, 参数2)
- 执行sql操作
- 得到结果
- 解析结果
- 释放资源
那么我们现在使用PreparedStament类对象防止上面的SQL注入
-
实现代码3-1:
package cn.gaogzhen.jdbc; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Scanner; import cn.gaogzhen.util.JDBCUtils; public class JDBCDemo8 { public static void main(String[] args) throws SQLException { Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String username = sc.nextLine().trim(); System.out.println("请输入密码:"); String password = sc.nextLine().trim(); sc.close(); String res = login(username, password)? "登录成功": "登录失败"; System.out.println(res); } public static boolean login(String username, String password) throws SQLException { if(username == null || password == null) return false; Connection conn = JDBCUtils.getConnection(); String sql = "select * from login where username = ? and password = ?"; PreparedStatement pstm = conn.prepareStatement(sql); pstm.setString(1, username); pstm.setString(2, password); ResultSet rs = pstm.executeQuery(); boolean flag = rs.next(); JDBCUtils.close(rs, pstm, conn); return flag; } }
测试结果:
请输入用户名:
sdfasf
请输入密码:
sdfas' or '1'='1#
登录失败
后记 :
本项目为参考某马视频开发,相关视频及配套资料可自行度娘或者联系本人。上面为自己编写的开发文档,持续更新。欢迎交流,本人QQ:806797785
前端项目源代码地址:https://gitee.com/gaogzhen/vue-leyou
后端JAVA源代码地址:https://gitee.com/gaogzhen/JAVA