JDBC之statement与preparedstatement的区别

昨天写了一篇jdbc的基本使用步骤,里面创建的sql命令发送器是statement,其实开发过程中,一般不使用这个,使用的是preparedstatment
–statement的缺点:

1.可读性差,比如登录需要字符串拼接,不直观
2.效率低下,在讲解preparedstatement时会分析这个
3.不安全,sql注入漏洞

下面我们使用statement模拟用户登录来讲解这些缺点

Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl");
Statement stmt = conn.createStatement();
//模拟用户输入账号密码
Scanner scanner = new Scanner(System.in);
System.out.println("请输入账号:");
String uname = scanner.next();
System.out.println("请输入密码:");
String upassword = scanner.next();
//使用拼接,语句比较繁琐
String sql = "select * from t_user where uname = '"+uname+"' and upassword = '"+upassword+"'";
//执行sql时,如果用户在输入账号或密码时使用or拼接一个true条件,那么这个条件都为真,这种情况就叫sql注入,不知道密码账号也能登录,例如:uname = aaa' or '1 = 1  或者upassword = aaa' or '1 = 1;
ResultSet rs = stmt.executeQuery(sql);
if(rs.next()){//如果有下一行返回true
    System.out.println("登录成功");
}else{
    System.out.println("登录失败");
}
--------------------------------
还有多次执行更新或者查询,虽然语句相似但是每次都要重新编译,效率低下
sql = "update ..where uid = 11";
sql = "update ..where uid = 22";
sql = "update ..where uid = 33";

使用preparedsatement可解决以上问题
preparedstatement:预处理,预编译;献上代码和注释一起理解它

//准备sql模板,供pstmt预编译加载到内存中
String sql = "select * from t_user where uname = ? and upassword = ?";//?代表占位符,内存会根据后面我们给的数据自动补充语句
//好处1,防止sql注入;2,代码明了,不需要自己拼接字符串
PreparedStatement pstmt = conn.preparedStatement(sql);
//上面的sql语句并未执行,只是加载到内存了预编译好了
//下面就是给问号赋值
pstmt.setString(1,"username");//这里1代表第一个问号,后面跟的是赋的值
pstmt.setString(2,"password");//2,第二个问好,setXXX()根据表的结构选择
//防注入的原理是预编译之后,preparedstatement不允许在填充数据的时候改变他的逻辑结构了
ResultSet rs = pstmt.executeQuery();//这里才是真正执行SQL语句
if(rs.next()){
System.out.println("登录成功");
}

你可能感兴趣的:(java-数据库)