Statement 和 PreparedStatement以及sql注入

Statement 和 PreparedStatement以及sql注入

Statement 和 PreparedStatement之间的关系和区别.

    关系:PreparedStatement继承自Statement,都是接口

    区别:PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高   

详解:

1、PreparedStatement:表示预编译的 SQL 语句的对象。

   接口:public interface PreparedStatement extends Statement之间的继承关系

   SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。

 

注意:

占位符 设置参数类型  与已知sql类型相同 setInt、setString setObject问号   第一个问号为1 第二个为2  依次类推

 

  例子:

      PreparedStatement pstmt = con.prepareStatement("UPDATE student name = ? where id= ?");

       pstmt.setString(1,张三)

       pstmt.setInt(2, 1002)

       pstmt.execute()//注意提交时这里不能再有sql语句,不同于Statement

2、Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。

   接口:public interface Statement extends Wrapper

在默认情况下,同一时间每个 Statement 对象只能打开一个 ResultSet 对象。因此,如果读取一个 ResultSet 对象与另一个交叉,则这两个对象必须是由不同的 Statement 对象生成的。如果存在某个语句的打开的当前 ResultSet 对象,则 Statement 接口中的所有执行方法都会隐式关闭它。 

   如以下操作:创建statement对象

          Statement stat=conn.createStatement();

          String sql="insert into student values(1002,'张三',to_date('21-9-2016','dd-mm-yyyy'))";

          stat.execute(sql);//这里提交时应该有sql语句,不同于PreparedStatment

附:

Statement 对象用于执行不带参数的简单 SQL 语句,类似于硬编码;PreparedStatement 对象用于执行带或不带参数的预编译 SQL 语句;CallableStatement 对象用于执行对数据库已存储过程的调用。

 

总结如下:

Statement每次执行sql语句,数据库都要执行sql语句的编译,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement.但存在sql注入风险。

PreparedStatement是预编译执行的。在执行可变参数的一条SQL时,PreparedStatement要比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率高。安全性更好,有效防止SQL注入的问题。对于多次重复执行的语句,使用PreparedStatement效率会更高一点。执行SQL语句是可以带参数的,并支持批量执行SQL。由于采用了Cache机制,则预编译的语句,就会放在Cache中,下次执行相同的SQL语句时,则可以直接从Cache中取出来。

                          String sql = "delete from tb_book where id="+id;

                           PreparedStatement pst = conn.prepareStatement(sql);

                             pst.execute(sql);//拼接的参数需要加sql

sql注入

什么是SQL注入,怎么防止SQL注入?

所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。

正常语句:

select id from users where username = '123 and password = '123'

sql注入语句:

那么如果我们在用户名处输入'or 1=1-- 而密码随便输入个456呢? 我们来看看数据库中的查询语句:

select id from users where username = '' or 1=1--  and password = '456'

'又 这里呢1=1永远为真,后面 and password = '456'被注释掉了。数据库不需要考虑,这里我们就跳过了验证。

怎么防止SQL注入

使用存储过程来执行所有的查询;

检查用户输入的合法性;

将用户的登录名、密码等数据加密保存。

Sql语句拼接 “+book.getId()+”

//编写sql语句-

           String sql="select * from tb_book where 1=1";

           //根据 id name 模糊查询 1=1为了拼接

           if(book.getId()!=null && !book.getId().equals("")){

                 sql+=" and id='"+book.getId()+"'";

           }

           if(book.getName()!=null && !book.getName().equals("")){

                 sql+=" and name like '%"+book.getName()+"%'";

           }

posted @   码农公子的幸福生活  阅读(104)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!
点击右上角即可分享
微信分享提示