PreparedStatement:解决sql语句注入问题,数据库连接池
一.PreparedStatement
(1)问题
SQL注入问题
在用户输入的信息和SQL语句进行字符串拼接。用户输入的内容作为了SQL语句语法的一部分,改变了原有SQL真正的意义,以上问题称为SQL注入。
-- 这条sql语句原有的含义是根据用户名和密码查询
-- 现在用户输入了一些特殊字符,改变了sql原有的含义,这种行为称为sql注入
//比如:
//请输入用户名:
haha
//请输入密码:
a' or '2'='2
//问题分析:
// 代码中的SQL语句
"SELECT * FROM user WHERE name='" + name + "' AND password='" + password + "';";
// 将用户输入的账号密码拼接后
"SELECT * FROM user WHERE name='haha' AND password='a' or '1'='1';"
要解决SQL注入就不能让用户输入的密码和我们的SQL语句进行简单的字符串拼接,需要使用PreparedStatement类解决SQL注入。
(2)PreparedStatement
解决SQL注入问题:
我们就不能让用户输入的信息和SQL语句进行字符串拼接,需要使用PreparedStatement对象解决SQL注入。
-- 在java语言中修复sql注入问题,通过占位符代替实际参数
SELECT * FROM USER WHERE username = ? AND password = ?
PreparedStatement基础语法:
// 1.获取连接
// 2.编写sql【占位符代替实际参数】
String sql = "SELECT * FROM USER WHERE name = ? AND password = ?";
// 3.获取sql预编译执行对象,先发送给数据库进行预编译
//PreparedStatement() 会先将SQL语句发送给数据库预编译。 PreparedStatement 会引用着预编译后的结
//果。可以多次传入不同的参数给 PreparedStatement 对象并执行。相当于调用方法多次传入不同的参数。
PreparedStatement pstmt = connection.prepareStatement(sql);
// 4.设置占位符实际参数
pstmt.setString(1,"admin'#");
pstmt.setString(2,"");
// 5.执行sql语句,并返回结果【注意,不需要传递sql参数】
ResultSet resultSet = pstmt.executeQuery();
// 6.处理结果
// 7.释放资源
(3)优点
1.
PreparedStatement()
会先将
SQL
语句发送给数据库预编译。
PreparedStatement
会引用着预编译后的结
果。可以多次传入不同的参数给
PreparedStatement
对象并执行。减少
SQL
编译次数,提高效率,提高性能。
2.
安全性更高,没有
SQL
注入的隐患。
3.
参数与sql分离,提高了程序的可读性
(4)PreparedStatement的Api介绍
===获取PreparedStatement的API介绍
在 java.sql.Connection 有获取 PreparedStatement 对象的方法
PreparedStatement PreparedStatement(String sql)会先将 SQL 语句发送给数据库预编译。 PreparedStatement 对象会引用着预编译后的结果。
PreparedStatement
的
API
介绍
在
java.sql.PreparedStatement
中有设置
SQL
语句参数,和执行参数化的
SQL
语句的方法
void setDouble ( int parameterIndex , double x )将指定参数设置为给定 Java double 值。
void setFloat ( int parameterIndex , float x )将指定参数设置为给定 Java float 值。
void setInt ( int parameterIndex , int x )将指定参数设置为给定 Java int 值。
void setLong(int parameterIndex, long x)将指定参数设置为给定 Java long 值。
void setObject(int parameterIndex, Object x)使用给定对象设置指定参数