博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JDBC之SQL注入,PreparedStatement和Statement
阅读量:2349 次
发布时间:2019-05-10

本文共 2646 字,大约阅读时间需要 8 分钟。

1、在SQL中包含特殊字符串或SQL的关键字(如:’or 1 or’)时,Statement将出现不可预料的结果(出现异常或查询的结果不正确),可用PreparedStatement来解决。
2、PreparedStatement(从Statement扩展而来)相对Statement的优点:
   ①没有SQL注入的问题;
   ②Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出;

   ③数据库和驱动可以对PreparedStatement进行优化(只有在相关联的数据库连接没有关闭的下有效);

   ④PreparedStatement效率比Statement效率高,但是在第一次执行的时候,PreparedStatement需要进行预编译处理,会比Statement效率低。

3、测试SQL注入SQLInject.java中的代码

package cn.itcast.jdbc;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import org.junit.Test;/** * 演示SQL注入,Statement和PreparedStatement的区别 */public class SQLInject {		/**	 * 这种方式会存在SQL注入的问题	 * @throws SQLException	 */	@Test	public void testStatement() throws SQLException {		//readByStatement("lisi");		//这里表示值是'或者1或者',即单引号		readByStatement("' or 1 or '");	}		/**	 * 使用这种方式经过测试查询不出结果	 * @throws SQLException	 */	@Test	public void testPreparedStatement() throws SQLException {		readByPreparedStatement("' or 1 or '");	}	/**	 * 使用PreparedStatement执行查询	 * @param name	 * @throws SQLException	 */	static void readByPreparedStatement(String name) throws SQLException {		Connection conn = null;		PreparedStatement ps = null;		ResultSet rs = null;				try{			//JdbcUtils参见上一篇博客			conn = JdbcUtils.getConnection();			String sql = "select id, name, money, birthday  from user where name=?";			//会对SQL语句进行预编译			ps = conn.prepareStatement(sql);			//注意下标从1开始			ps.setString(1, name);			//执行语句			rs = ps.executeQuery();						//处理结果			while(rs.next()) {				System.out.println(rs.getInt("id") + "\t"						+ rs.getString("name") + "\t" 						+ rs.getDate("birthday")						+ "\t" + rs.getFloat("money"));			}		}finally{			JdbcUtils.free(rs, ps, conn);		}			}		/**	 * 通过Statement查询数据,存在SQL注入的问题	 * @param name	 * @throws SQLException	 */	static void readByStatement(String name) throws SQLException {		Connection conn = null;		Statement st = null;		ResultSet rs = null;				try{			conn = JdbcUtils.getConnection();			conn.getAutoCommit();			st = conn.createStatement();			String sql =  "select id, name, money, birthday  from user where name='"					+ name + "'";			System.out.println("SQL:" + sql);			rs = st.executeQuery(sql);			while(rs.next()) {				System.out.println(rs.getInt("id") + "\t"						+ rs.getString("name") + "\t" + rs.getDate("birthday") 						+ "\t" + rs.getFloat("money"));			}		} finally {			JdbcUtils.free(rs, st, conn);		}	}}

测试结果:

运行testStatement方法,得到如下结果(数据库中的结果全部被查询来):

SQL:selectid, name, money, birthday  from userwhere name='' or 1 or ''

1   zhangsan   2017-06-30 110.0

2   lisi   2017-06-06 210.0

3   wangwu 2017-05-30 310.0

4   name1  1987-01-01 410.0

 

运行readByPreparedStatement方法,打印不出任何结果。

转载地址:http://cklvb.baihongyu.com/

你可能感兴趣的文章
Spring Cloud 2.x完整入门Demo样例(Greenwich版本)
查看>>
Spring Cloud 2.x学习笔记:2、feign改进(Greenwich版本)
查看>>
SpringCloud 2.x学习笔记:3、Hystrix(Greenwich版本)
查看>>
SpringCloud 2.x学习笔记:4、Zuul(Greenwich版本)
查看>>
ajax提交JSON数组及Springboot接收转换为list类
查看>>
SpringCloud 2.x学习笔记:5、Config(Greenwich版本)
查看>>
RabbitMQ安装、配置与入门
查看>>
Ibatis代码自动生成工具
查看>>
ant build.xml教程详解
查看>>
彻底理解ThreadLocal
查看>>
STM32 HAL库、标准外设库、LL库(STM32 Embedded Software)
查看>>
基于STM32CubeMX创建STM32L496ZGTx的工程
查看>>
如何通过OpenFace实现人脸识别框架
查看>>
Angle和XBGoost以及Spark的性能对比
查看>>
Node.js & Electron的扩展模块
查看>>
Mysql semi-sync VS group replication, 谁快?
查看>>
碎片清理
查看>>
程序员不能错过的技术网站
查看>>
冒泡排序(分析+代码调优)
查看>>
Vue
查看>>