Java连接数据库 CreateStatement 和 PrepareStatement 的区别与优劣
一、简介
先说下CreateStatement 和 PrepareStatement 这俩到底是干啥的吧。
作用:其实这俩干的活儿都一样,就是创建了一个对象然后去通过对象调用executeQuery方法来执行sql语句。
区别:其实就是Statement和PrepareStatement的区别,最明显的区别,就是执行的sql语句格式不同
二、案例说明
2.1 需求1
我们有一个数据库,里面有一个user表,有username,userpwd两列。我们要查出这两列的数据
2.2 java两种方式实现方式
createStatement方式
String sql = "select * from users where username= '"+username+"' and userpwd='"+userpwd+"'";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
PrepareStatement方式
String sql = "select * from users where username=? and userpwd=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username);
pstmt.setString(2, userpwd);
rs = pstmt.executeQuery();
相信写到这,大家很多人就能看出来了
优点一:原来PrepareStatement跟Statement的主要区别就是把上面sql语句中的变量抽出来了
优点二:PrepareStatement可以提高代码的可读性。
什么?你没觉得这有什么可以提高可读性的?那好,咱来看看下面这两段代码,看完你再说话。
2.3 需求2
我们有一个数据库,里面有一个book表,有bookid,bookname,bookauthor,booksort,bookprice五列。我们要向这个表中添加一部分数据。
createStatement方式
String sql = "insert into book (bookid,bookname,bookauthor,booksort,bookprice) values ('"+var1+"',
'"+var2+"',"+var3+",'"+var4+","+var5+"')";
stmt = conn.createStatement();
rs = stmt.executeUpdate(sql);
PrepareStatement方式
String sql = "insert into book (bookid,bookname,bookauthor,booksort,bookprice) values (?,?,?,?,?)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1,var1);
pstmt.setString(2,var2);
pstmt.setString(3,var3);
pstmt.setString(4,var4);
pstmt.setString(5,var5);
pstmt.executeUpdate();
对比后怎么样,可以提高代码可读性了吗?反正打这行代码的时候,整个引号逗号就给我刺激懵了。
2.4 优点三:ParperStatement提高了代码的灵活性和执行效率。
PrepareStatement接口是Statement接口的子接口,他继承了Statement接口的所有功能。它主要是拿来解决我们使用Statement对象多次执行同一个SQL语句的效率问题的。ParperStatement接口的机制是在数据库支持预编译的情况下预先将SQL语句编译,当多次执行这条SQL语句时,可以直接执行编译好的SQL语句,这样就大大提高了程序的灵活性和执行效率。
2.5 优点四:ParperStatement比Statement好的优点,那就是安全
你说啥?这还关安全啥事儿,那我给你一行代码,你来给我说说这是干嘛的。
String sql = "select * from user where username= '"+varname+"' and userpwd='"+varpasswd+"'";
stmt = conn.createStatement();
rs = stmt.executeUpdate(sql);
这是验证用户名密码的,对吧。但要是我们把'or '1' = 1'当作密码传进去,你猜猜会发生啥。
select * from user where username = 'user' and userpwd = '' or '1' = '1';
发现了吧!这是个永真式,因为1永远等于1。所以不管怎样都能获取到权限。哇。这就坏咯!这还不是最坏的,你再看!
String sql = "select * from user where username= '"+varname+"' and userpwd='"+varpasswd+"'";
stmt = conn.createStatement();
rs = stmt.executeUpdate(sql);
依旧是这行代码。这次我们把'or '1' = 1';drop table book;当成密码传进去。哇!又坏了!这次直接把表给删了。但是,你如果用PrepareStatement的话就不会出现这种问题。你传入的这些数据根本不会跟原来的数据有任何的交集,也不会发生这些问题。
参考博客:https://blog.csdn.net/u011161786/article/details/48394751