为什么80%的码农都做不了架构师?>>>   

尽管自己写代码用了preparedstatement, 但是对于它和statement 之间的区别不是非常了解。 正好今天有时间学习实践一下, 尤其是sql 注入。

1 代码实践

首先比较一下statement 和preparedstatement 的调用方式, 后者的调用代码量稍多一些 -网上找的

Statement:

stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");

preparedStatement:

perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate();

2 preparedSatement 的优点

1) 允许动态和参数化的query; 易于维护
2) 运行效率快

其实就是预编译的问题。 PreparedSatement 会预编译, 而Statement基本上无法重用。 所以多次执行的话前者效率高很多。 生产环境中遇到过这种情况, 有几万条sql, 数据库的工作效率严重下降, 后来通过替换成PreparedStatement解决了这个问题

每一种数据库都会尽最大努力对预编译语句提供最大的性能优化.因为预编译语句有可能被重复调用.所以语句在被DB的编译器编译后的执行代码被缓存下来,那 么下次调用时只要是相同的预编译语句就不需要编译,只要将参数直接传入编译过的语句执行代码中(相当于一个涵数)就会得到执行.这并不是说只有一个 Connection中多次执行的预编译语句被缓存,而是对于整个DB中,只要预编译的语句语法和缓存中匹配.那么在任何时候就可以不需要再次编译而可以 直接执行.

而statement的语句中,即使是相同一操作,而由于每次操作的数据不同所以使整个语句相匹配的机会极小,几乎不太可能匹配.比如:

insert into tb_name (col1,col2) values ('11','22');
insert into tb_name (col1,col2) values ('11','23');

即使是相同操作但因为数据内容不一样,所以整个个语句本身不能匹配,没有缓存语句的意义.事实是没有数据库会对普通语句编译后的执行代码缓存.

当然并不是所以预编译语句都一定会被缓存,数据库本身会用一种策略,比如使用频度等因素来决定什么时候不再缓存已有的预编译结果.以保存有更多的空间存储新的预编译语句.

3) 安全性 预防sql注入的攻击

开始没有明白这点, 后来从stackflow 查到一个例子,就很容易理解了。

Statement stmt = conn.createStatement("INSERT INTO students VALUES('" + user + "')");
stmt.execute();

Or

Statement stmt = conn.prepareStatement("INSERT INTO student VALUES(?)");
stmt.setString(1, user);
stmt.execute();

If "user" came from user input and the user input was

Robert'); DROP TABLE students; --

然后自己写了代码实践了一下, 发现确实如果statement 会把 table drop掉。 而prepared的呢因为已经预编译了, 根本就不会执行这个drop语句。 所以是安全的。 

3 实例

如何使用以及如何测试依赖注入, 这里是本地 postgres 数据库, 用户名密码postgres postgres

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class PreparedStmtExample {public static void main(String args[]) throws SQLException {System.out.println("-------- PostgreSQL " + "JDBC Connection Testing ------------");try {Class.forName("org.postgresql.Driver");} catch (ClassNotFoundException e) {System.out.println("Where is your PostgreSQL JDBC Driver? " + "Include in your library path!");e.printStackTrace();return;}System.out.println("PostgreSQL JDBC Driver Registered!");// statementConnection conn = DriverManager.getConnection( "jdbc:postgresql://127.0.0.1:5432/postgres", "postgres", "postgres");
//        String name = "'name'";String name1 = "'name'; drop table table1;";Statement stmt = conn.createStatement();
//        ResultSet result = stmt
//                .executeQuery("select * from network where id="
//                        + name1);ResultSet result = stmt.executeQuery("select * from network where id="+ name1);while (result.next()) {System.out.println("Loan Type: " + result.getString("sid"));}// preparedstatementConnection conn1 =DriverManager.getConnection("jdbc:postgresql://127.0.0.1:5432/postgres", "postgres", "postgres");PreparedStatement preStatement = conn1 .prepareStatement("select * from network where id=?");preStatement.setString(1, "name; drop table table1;");ResultSet result1 = preStatement.executeQuery();while (result1.next()) {System.out.println("Loan Type: " + result1.getString("sid"));}}
}

要预先create 一个table :network, column id,sid; 加一个record name;xxx 即可。
    create 第二个table: table1

4 结论与其他

这次主要理解了如何使用,以及如何防止sql注入。 以后一般就直接用preparedStatement 即可。

Next

1) 关于sql 执行过程原理是否可以理解一下

5 参考

1)Why use PreparedStatement in Java JDBC – Example Tutorial

http://javarevisited.blogspot.com/2012/03/why-use-preparedstatement-in-java-jdbc.html

转载于:https://my.oschina.net/sizhe/blog/489450

为什么用preparedStatement 而不是statement相关推荐

  1. JDBC为什么要使用PreparedStatement而不是Statement

    本文转载自 JDBC为什么要使用PreparedStatement而不是Statement PreparedStatement是用来执行SQL查询语句的API之一,Java提供了 Statement. ...

  2. 【转】JDBC为什么要使用PreparedStatement而不是Statement

    http://www.importnew.com/5006.html PreparedStatement是用来执行SQL查询语句的API之一,Java提供了 Statement.PreparedSta ...

  3. MySQL JDBC PreparedStatement

    JDBC作为JAVA访问数据库的一套规范与标准,统一了数据库操作的API,大大简化了程序开发工作.不过由于历史原因,MySQL对JDBC默认的实现与规范定义或者说其它数据库如Oracle并不一致,为了 ...

  4. JDBC常见面试题集锦(二)

    JDBC的保存点(Savepoint)是什么,如何使用? 有时候事务包含了一组语句,而我们希望回滚到这个事务的某个特定的点.JDBC的保存点可以用来生成事务的一个检查点,使得事务可以回滚到这个检查点. ...

  5. JDBC的开发流程是什么?

    1.注册驱动 (Class.forName) 2.获得连接(DriverManager.getConnection()) 3.获得执行者对象 (通过连接对象获取Statement或者PrepareSt ...

  6. 为什么要用Mybatis框架---Mybatis学习笔记(一)

    首先使用原生态的JDBC来操作数据库,从中发现存在的一些问题: jdbc代码: public class JdbcTest {public static void main(String[] args ...

  7. 性能测试系列:Jmeter使用记录

    1.做接口测试,服务器是10台docker,目标是把10台docker的cpu压满.我有三台压力机,windows Server操作系统,4c8g配置. 经过尝试,每台压力机发起700vu,压力机cp ...

  8. jdbc教程_JDBC教程

    jdbc教程 Welcome to JDBC tutorial. Java DataBase Connectivity (JDBC) is one of the most widely used AP ...

  9. java 防止sql注入_Java中SQL注入以及如何轻松防止它

    java 防止sql注入 什么是SQL注入? (What is SQL Injection?) SQL Injection is one of the top 10 web application v ...

  10. 2020年Java最新面试题整理题库完整版

    JAVA面试题 一.JavaSE编程基础 JDK,JRE,JVM三者关系 a. .jdk是JAVA程序开发时用的开发工具包,其内部也有JRE运行环境JRE. b. .JRE是JAVA程序运行时需要的运 ...

最新文章

  1. nyoj-Color the necklace(Ploya定理 + 欧拉函数 + 扩展欧几里得(求逆元))
  2. Python学习笔记:多线程和多进程(转1)
  3. php mysql 内存溢出_关于MySQL的整型数据的内存溢出问题的应对方法_MySQL
  4. 移动硬盘磁盘结构损坏且无法读取要怎样办啊
  5. 计算机组成与架构综述学习报告
  6. 李洪强-C语言2-字符串
  7. MYSQL--事务隔离
  8. matlab abc to dq0仿真,逆变器负载论文,关于基于同步旋转坐标的三相逆变器控制系统仿真相关参考文献资料-免费论文范文...
  9. 中国磷酸一铵(MAP)行业市场供需与战略研究报告
  10. 使用servlet实现果树管理系统功能实现,小项目详解,点击链接,可以获得全部源代码
  11. centos下mysql备份数据库命令_[CentOS]下mysql数据库常用命令总结
  12. 网易 android 加密,解析网易云音乐的加密方式
  13. 拯救者Y7000在ubuntu下的1660Ti驱动安装
  14. 2018计算机考研国家线预测,2018考研国家线预测及解读-考研帮(kaoyan.com)
  15. [跟进]_中国银联悄然推出B2C网站-银联在线商城
  16. 用python求圆的表面积_【用python写一组类(class)对应各种几何体(正方体,长方体,球,圆柱)的表面积和体积的编码】作业帮...
  17. ASCII 字母字符 63———127
  18. 华栖云携阿里云首发云上电视台服务:致力于把电视台搬上云端
  19. php伪协议xss,XSS漏洞学习
  20. x58和x79服务器性能,X58接班人:2012年Intel最牛主板X79规格曝光

热门文章

  1. [C] C语言中的布尔值
  2. RobotFramework自动化测试框架-移动手机自动化测试Clear Text关键字的使用
  3. 移动web:tab选项卡
  4. UVa 10325 - The Lottery
  5. 常用的php类、方法、函数 注释标记
  6. 易语言 word类excel类 的 源码和模块
  7. [Python]小甲鱼Python视频第020课(函数:内嵌函数和闭包)课后题及参考解答
  8. vue组件,通过props父组件给子组件传值,WTF, 子组件报错undefined???
  9. Android应用资源分析(老罗链接整理)
  10. windows下把文件压缩成tar.gz格式