1.出现原因(作用)
1.Statement 对象每次执行sql语句时,都会对其进行编译,从而降低了数据库访问效率。
2.其次,statement不安全,会被注入攻击。
例如用户登录的时候查询SQL拼装语句为:
String sql = “select * from tb_user where name = '” + username + “’ and passwd = '” + password + “’”;
若在用户名栏输入:asdfgsaf(任意字符),在密码栏输入:,则拼装后的 SQL语句为:
select * from tb_user where name = 'asdfgsaf' and passwd =abc' or '1'='1',
则此语句永远都能正确执行,从而实现注入方式攻击。如果使用PreparedStatement,则会将输入的内容全部解析为字符串,而不会出现此漏洞。
代码演示
package data1202.itcast.jdbc;
/*
prepareStatement对象实现jdbc
*/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JdbcDemop {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps =null;
try {
//加载数据库驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//创建应用程序与数据库的连接对象
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db1?serverTimezone=GMT%2B8", "root", "root");
//执行的sql语句
String sql = "insert into account values(?,?,?)";
//创建执行sql语句的prepareStatement对象
ps = conn.prepareStatement(sql);
//为sql语句中的参数赋值
ps.setInt(1,4);
ps.setString(2,"Alice");
ps.setInt(3,888);
//执行sql语句
ps.executeUpdate();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if (ps!=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
结果截图: