本文主要讲了PrepareStatement和CreateStatement的作用区别,大家可以一起学习!走后端的小伙伴都会必修JDBC,在前段时间作者实训期间,看到老师举例的时候用了CreateStatement(当然老师只是随便举得例子)。而本人的个人习惯是用PrepareStatement的,作者之前是很困惑过这两个之间的区别的,在实践之后以及看的一些资料积攒了一些看法,在这里和大家谈一下CreatStatement和PrepareStatement的作用和区别吧。(图为老师的案例)
作用:这两者作用基本一样,来看两者代码的写法。两者在JDBC连接数据库时用法基本一样,都是创建了一个数据库的操作对象,然后让该对象调用excuteQuery执行相应的sql语句。所以在JDBC中这俩其实最后达成的效果是一样的。
区别:CreateStatement和PrepareStatement的最明显的区别首先自然是写法上面了。来直接看代码:
代码背景:假设我们数据库里面有一张关于book的表,里面有bid和bname两列,现在进行查询两列数据这个简单的操作。
这是用PrepareStatement创建的ps操作对象的过程(为了增强对比性其余片段先省略掉)
//创建sql命令 String sql="select *from user where bid=? and bname=?"; //创建sql操作对象 ps=conn.prepareStatement; //给占位值赋值 ps.setString(1,bid); ps.setString(2,bname); //执行sql命令 rs=ps.executeQuery();
这是用CreatStatement创建的st操作对象的过程
//创建sql命令 String sql="select *from book where bid='"+bid+"' and bname='"+bname"'"; //创建数据库操作对象 st=conn.createStatement; //执行sql命令 rs=st.executeQuery(sql);
从代码上相信很多人就可以看出两个人写法上的区别了,PrepareStatement和CreateStatement的写法就是前者将sql语句中的变量抽离出来了。你品,你细品。有没有从这发现PrepareStatement的一大优点:可读性强!什么?你没有发现?如果我们原来数据库中的book表多了bdescn,bprice,bauthor这三列。我们往这五列添加数据,两个代码的样子又变成什么样子了呢?
Createment的是这样的:
String sql = "insert into book (bid,bname,bauthor,bdescn,bprice) values("+var1+'"+var2+"',"+var3+",'"+var4+","+var5+"')"; st = conn.createStatement(); rs = st.executeUpdate(sql);
PrepareStatement是这样的
String sql = "insert into book (boid,bname,bauthor,bdescn,bprice) values(?,?,?,?,?)"; ps=conn.prepareStatement(sql); ps.setString(1,var1); ps.setString(2,var2); ps.setString(3,var3); ps.setString(4,var4);
ps.setString(5,var5); pst.executeUpdate();
这样看应该是非常清晰了吧,CreateStatement在写的时候要注意的太多了,而且标点符号啥的一点都不能错。否则程序就会报错,这谁顶得住呀!
当然不止这一个区别。PrepareStatement从“伦理”上面来说应该是诞生于CresteStatement,也就是CreateStatement是它爸!!所以CreateStatement上面的所有优点都被PrepareStatement完美的继承了。就拿上面的举例,实际上Createment的工作原理就是将String sql="insert into book values()"执行了多次,而PrepareStatement工作原理则相反,是先将相应的sql语句编译好,之后有对象执行这条sql语句时,直接调用相应编译好的sql语句时就好。所以后者的工作效率就会明显的比前者高,当然也就更加灵活啦。
最后,就是最重要的一个区别了。那就是PrepareStatement的安全性比“他爸”高了非常多,你在看上面的代码,你品,你细品。如果看不出来的话我给大家换一个,如果使用CreateStatement创造数据库操作对象去验证用户的账号密码的时是不是下面这么操作的呢?
String sql = "select * from user where username= '"+varname+"' and userpwd='"+varpasswd+"'";
st = conn.createStatement();
rs = st.executeUpdate(sql);
有没有感觉有什么不对的地方呢??你看,假使我们在知道一个用户的用户名却不知道密码的时候,将or '1' = '1'当作密码传进去会发生什么呢?句子就变成这样子了select * from user where username = 'user' and userpwd = '' or '1' = '1'是不是就会惊奇的发现,这竟然是一个恒等式!!所以想要得到你的权限去干事情就变得非常简单,比如添加一个在'or '1' = 1'添加一个drop table book是不是你这一个表就消失了呢?而用它的“儿子”就完全不会出现这种情况,因为PrepareStatement在运行的过程中都是独立的,数据也都是独立运行的,所以影响没有那么大的!
好啦,就讲到这了,希望可以给你一点帮助!