当我们使用java程序来操作sql server时会使用到Statement和PreparedStatement,俩者都可以用于把sql语句从java程序中发送到指定数据库,并执行sql语句。那么如何进行一个较好的选择?

首先,我们来看俩者的区别:

Statement和PreparedStatement的区别(1)

1、直接使用Statement,驱动程序一般不会对sql语句作处理而直接交给数据库;使用PreparedStamen,形成预编译的过程,并且会对语句作字符集的转换(至少在sql server)中如此。

如此,有两个好处:对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch;另外,可以比较好地解决系统的本地化问题。

2、PreparedStatement还能有效的防止危险字符的注入,也就是sql注入的问题。(但是必须使用“对?赋值的方法”才管用)

我们用一个实例来进行演示:

PreparedStatement的使用[Sql_test2.java]

/**

* PreparedStatement使用CRUD

*1、PreparedStatement可以提高执行效率(因为它有预编译的功能)

*2、PreparedStatement可以防止SQL注入,但是要求用?赋值的方式才可以

*/

packagecom.sqlserver;

importjava.sql.*;

publicclass Sql_test2 {

public static void main(String[] args) {

Connection ct=null;

PreparedStatement ps=null;

ResultSet rs=null;

try {

//1、加载驱动(把需要的驱动程序加入内存)

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

//2、得到连接(指定连接到哪个数据源、数据库的用户名和密码)

ct=DriverManager.getConnection("jdbc:odbc:mytest","sa","sa");

//3、创建PreparedStatement

//PreparedStatement用处:主要用于发送SQL语句到数据库

//          ps=ct.prepareStatement("select *from dept where deptno=? and loc=?");

//          //给?赋值(可防止SQL注入漏洞问题),不要直接使用拼接的方式

//          ps.setInt(1, 20);

//          ps.setString(2, "dallas");

//          //演示:查询,显示所有的部门信息

//          //ResultSet结果集,大家可以把ResultSet理解成返回一张表行的结果集

//          rs=ps.executeQuery();

//          //循环取出

//          while(rs.next()){

//              int a=rs.getInt(1);

//              String b=rs.getString(2);

//              String c=rs.getString(3);

//              System.out.println(a+"\t"+b+"\t"+c);

//          }

//使用PreparedStetement添加一条记录

//          ps=ct.prepareStatement("insert into dept values(?,?,?)");

//          ps.setInt(1, 60);

//          ps.setString(2, "安全部");

//          ps.setString(3, "上海");

//          //执行

//          int i=ps.executeUpdate();

//          if(i==1){

//              System.out.println("添加成功");

//          }else{

//              System.out.println("添加失败");

//          }

//使用PreparedStetement修改一条记录从dept表中修改loc=上海deptno改为50

//          ps=ct.prepareStatement("update dept set deptno=? where loc='上海'");

//          ps.setInt(1, 50);

//          //执行

//          int i=ps.executeUpdate();

//          if(i==1){

//              System.out.println("修改成功");

//          }else{

//              System.out.println("修改失败");

//          }

//使用PreparedStetement删除一条记录

ps=ct.prepareStatement("delete from dept where deptno=?");

ps.setInt(1, 50);

int i=ps.executeUpdate();

if(i==1){

System.out.println("删除成功");

}else{

System.out.println("删除失败");

}

} catch (Exception e) {

e.printStackTrace();

}finally{

//关闭资源,关闭顺序先创建后关闭,后创建先关闭

try {

if(rs!=null){

rs.close();

}

if(ps!=null){

ps.close();

}

if(ct!=null){

ct.close();

}

} catch (SQLException e) {

e.printStackTrace();

}

}

}

}

此段代码比较容易理解,使用了PreparedStatement,其中对问号(?)的赋值防止了SQL的危险注入问题。

如果使用Statement,则在有时候会产生危险注入。比如,一个database中有一张表user

create table  user

{

username   varchar(30)

passwd     varchar(30)

}

insert  into user values('ywq' , 'ywqwd')

select * from user where username='ywq' and passwd='ywqwd'

通过以上语句将建立一张表,并且将数据查询显示出来。

然而问题就出现在这儿!!!当我们写成select * from user where username='ywq' and passwd='ffwd' or 1='1'的时候,还是可以查询并且显示出数据,这就意味着前面的用户名和密码成为了虚设的,不起任何作用。如此看来,漏洞就在这儿。

当使用Statement时,ps=ct.createStatement("select *from dept where deptno='10' and loc='北京'");此语句将产生危险注入,导致系统不安全。所以我们很有必要使用PreparedStatement。

修改之后的代码如下所示:

ps=ct.prepareStatement("select * from user where username=? and passwd=?");

ps.setString(1, "ywq");

ps.setString(2, "ywqwd");

此时将正确查询到数据。当第三行改为:ps.setString(2,""ywqwd" or 1=1") 时将得不到正确结果。

总结下对问号?赋值的格式如下所示:

ps=ct.prepareStatement("insert into dept values(?,?,?)");

ps.setInt(1, 60);

ps.setString(2, "安全部");

ps.setString(3, "上海");

其中后三句分别对第一句中的?进行赋值。

此时较好的解决了危险注入的问题。

转载于:https://www.cnblogs.com/lanzhi/p/6467348.html

浅析Statement和PreparedStatement的区别相关推荐

  1. Statement与PreparedStatement的区别

    Statement与PreparedStatement的区别 PreparedStatement预编译SQL语句,性能好. PreparedStatement无序拼接SQL语句,编程更简单. Prep ...

  2. 数据库SQL Server2012笔记(八)——Statement与PreparedStatement的区别,JDBC方式操作数据库...

    1.Statement与PreparedStatement的区别 1)都可用于  把sql语句从java程序中发送到制定数据库,并执行sql语句. 2)区别 直接使用Statement,驱动程序一般不 ...

  3. Statement和PreparedStatement的区别/PreparedStatement和Statement比较的优点

    Statement 和 PreparedStatement之间的关系和区别.     关系:PreparedStatement继承自Statement,都是接口     区别:PreparedStat ...

  4. Statement和PreparedStatement的区别及联系

    两者之间的联系: Statement和PreparedStatement两者都是用来执行SQL查询语句的API之一 PreparedStatement接口继承了Statement接口 两者之间的区别: ...

  5. JDBC中Statement与PreparedStatement的区别

    http://www.blogjava.net/redcoatjk/archive/2012/07/20/383583.html 1. statement每次执行sql语句,相关数据库都要执行sql语 ...

  6. JDBC中的Statement 和PreparedStatement的区别?

    PreparedStatement 继承于 Statement Statement 一般用于执行固定的没有参数的SQL PreparedStatement 一般用于执行有?参数预编译的SQL语句. P ...

  7. java Statement与preparedStatement的区别

    1.数据库执行preparedStatement的时候会预编译,下次再执行此sql语句的时候,数据库端将不会再进行预编译了,而直接去数据库的缓存区,提高访问的效率. 2.在任何时候都不要使用State ...

  8. JDBC中的Statement和PreparedStatement的区别

    PreparedStatement是什么?PreparedStatement是java.sql包下面的一个接口,用来执行SQL语句查询,通过调用connection.preparedStatement ...

  9. JDBC自我复习之Statement和PreparedStatement的区别

    一.Statement 1.1 介绍 Statement 是 Java 执行数据库操作的一个重要接口,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句. Statement对象,用于执 ...

最新文章

  1. 全变量进气系统伺服马_三种伺服电动缸系统的特点
  2. 03.结构化机器学习项目 W1.机器学习策略(1)
  3. 【图像处理】直方图均衡化(附带Matlab及OpenCV3自编程实现代码)
  4. springboot 打印slf4_SpringBoot里slf4j日志功能的默认实现
  5. vue 执行函数this_vue回调函数中this无效
  6. 这家初创公司用端到端安全保护物联网设备
  7. Maven使用{PDF报表时导入坐标报错,解决·Cannot resolve com.lowagie:itext:2.1.7.js6
  8. 学计算机的能看出批图吗,P过的图片能看出来吗?给你4个鉴别方法!
  9. 我和谷歌共同成长----Andriod(安卓)开发(持续更新)
  10. Zemax学习笔记——序列模式点光源与平行光设置
  11. 4.2.5 Kafka集群与运维(集群的搭建、监控工具 Kafka Eagle)
  12. 内存(DDR/DDR2/DDR3/DDR4)的速度等级和时钟频率———个人笔记
  13. oracle11G修改数据库默认端口
  14. 年轻人猝死频发,AI应用到心血管疾患筛查还有多远?
  15. KAL 推出 Kalignite Hypervisor 解决方案—引领 ATM 硬件更新创新模式
  16. 面向需求编程才是常态,聊聊我的经历
  17. “跑路风波”的内在缘由?P2P网络信贷将何去何从?
  18. 写一个函数,用户输入一个数判断是否是素数,并返弹出回值(又叫质数,只能被1和自身整数的数)
  19. 《遥感图像处理笔记》第1章
  20. 视频号如何认证个人黄V认证

热门文章

  1. 轻音乐背后的故事_研究背后的故事
  2. 霍尼韦尔门禁说明书_霍尼韦尔智能家居 门禁密码锁怎么改密码
  3. oracle owb下载,oracle 11g workflow 安装说明
  4. mysql还原.bak文件_mysql还原bak文件
  5. 【深度学习基础】数字手势识别实验:2.MLP
  6. web服务器并发量计算
  7. 什么类型的短视频更容易吸粉?分享三种短视频类型,可参考
  8. [TPAMI-2023] Effective Local and Global Search for Fast Long-Term Tracking
  9. 爬取5K分辨率超清唯美壁纸
  10. Goland调节字体大小(编辑区,terminal区,页面字体)