当我们使用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

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

*、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, "上海");

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

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

浅析Statement和PreparedStatement的区别的更多相关文章

  1. JDBC中的Statement和PreparedStatement的区别

    JDBC中的Statement和PreparedStatement的区别  

  2. Statement和PreparedStatement的区别; 什么是SQL注入,怎么防止SQL注入?

    问题一:Statement和PreparedStatement的区别 先来说说,什么是java中的Statement:Statement是java执行数据库操作的一个重要方法,用于在已经建立数据库连接 ...

  3. Statement和PreparedStatement的区别; 什么是SQL注入,怎么防止SQL注入? (转)

    问题一:Statement和PreparedStatement的区别 先来说说,什么是java中的Statement:Statement是java执行数据库操作的一个重要方法,用于在已经建立数据库连接 ...

  4. Statement与PreparedStatement的区别

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

  5. [转] JDBC中的Statement和PreparedStatement的区别

    以Oracle为例吧 Statement为一条Sql语句生成执行计划,如果要执行两条sql语句select colume from table where colume=1;select colume ...

  6. JDBC与Statement和PreparedStatement的区别

    一.先来说说,什么是java中的Statement:Statement是java执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句.具体步骤: 1.首先导入 ...

  7. 7.秋招复习简单整理之请你讲讲 Statement 和 PreparedStatement 的区别?哪个性能更好?

    Statement和PreparedStatement都是数据库用于执行SQL语句的句柄,但是PreparedStatement代表一个预编译的SQL. 以下是PreparedStatement和St ...

  8. statement和preparedstatement用法区别

    1. PreparedStatement接口继承Statement, PreparedStatement 实例包含已编译的 SQL 语句,所以其执行速度要快于 Statement 对象.   2.作为 ...

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

    PreparedStatement是预编译的SQL语句,效率高于Statement. PreparedStatement支持操作符,相对于Statement更加灵活. PreparedStatemen ...

随机推荐

  1. 关于谷歌浏览器默认字体12px的解决方案

    1. * Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示, 可通过加入 CSS 属性 -webkit-text-size-adjust: none; 解决. 超链接访问 ...

  2. How to create a List of ValueTuple?

    ValueTuple需要通过NuGet安装System.ValueTuple https://docs.microsoft.com/en-us/dotnet/csharp/tuples?view=ne ...

  3. 织梦CMS如何在首页调用指定的文章 idlist

    在网站首页调用站内新闻是必不可少的,但是有的时候不能根据自己的需要来调用指定的文章,想要调用自己指定的文章还要做一些修改. 在网站中调用指定文章可以使用织梦默认的标签idlist,在调用的时候使用以下 ...

  4. 构造方法,重载,static,math类(java基础知识七)

    1.构造方法概述和格式 * A:构造方法概述和作用     * 给对象的数据(属性)进行初始化 * B:构造方法格式特点     * a:方法名与类名相同(大小也要与类名一致)     * b:没有返 ...

  5. cf 620C Pearls in a Row(贪心)

    d.有一串数字,要把这些数字分成若干连续的段,每段必须至少包含2个相同的数字,怎么分才能分的段数最多? 比如 是1 2 1 3 1 2 1 那么 答案是 21 34 7 即最多分在2段,第一段是1~3 ...

  6. golang defer使用——资源关闭时候多用

    defer Go语言中有种不错的设计,即延迟(defer)语句,你可以在函数中添加多个defer语句.当函数执行到最后时,这些defer语句会按照逆序执行,最后该函数返回.特别是当你在进行一些打开资源 ...

  7. linux防火墙过滤规则

    一.linux防火墙基础 防火墙分为硬件防火墙和软件防火墙. 1.概述 linux 防火墙体系主要工作在网络层,针对TCP/IP数据包实施过滤和限制,属于典型的包过滤防火墙. 包过滤机制:netfil ...

  8. codeforces 505C C. Mr. Kitayuta, the Treasure Hunter(dp)

    题目链接: C. Mr. Kitayuta, the Treasure Hunter time limit per test 1 second memory limit per test 256 me ...

  9. 机器学习 Hidden Markov Models 3

    Viterbi Algorithm 前面我们提到过,HMM的第二类问题是利用HMM模型和可观察序列寻找最有可能生成该观察序列的隐藏变量的序列.简单来说,第一类问题是通过模型计算生成观察序列的概率,而第 ...

  10. CS231n 2016 通关 第一章-内容介绍

    第一节视频的主要内容: Fei-Fei Li 女神对Computer Vision的整体介绍.包括了发展历史中的重要事件,其中最为重要的是1959年测试猫视觉神经的实验. In 1959 Harvar ...