您的位置:首页 > 数据库

PreparedStatement与Statement对比、sql语句的被注入问题

2016-12-04 15:11 393 查看
PreparedStatement vs Statment

一、语法不同:PreparedStatement可以使用预编译的sql,而Statement只能使用静态的sql。

二、效率不同: PreparedStatement可以使用sql缓存区,效率比Statement高。



三、安全性不同: PreparedStatement可以有效防止sql注入,而Statement不能防止sql注入。

通过案例对比来给大家讲解这一点:

1、Statement模拟用户登陆:

package sram.login;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import org.junit.Test;

import sram.util.jdbc.JdbcUtil;
/**
* 模拟用户登录效果
*/
public class Demo1 {
//模拟用户输入
private String name = "zhangsan";
private String password = "123";
@Test
public void testByStatement(){
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
//获取连接
conn = JdbcUtil.getConnection();
//创建Statment
stmt = conn.createStatement();
//准备sql
//注意带参的sql语句的书写
String sql = "SELECT * FROM admin WHERE userName='"+name+"' AND pwd='"+password+"'";
System.out.println(sql);
//执行sql
rs = stmt.executeQuery(sql);
if(rs.next()){
//登录成功
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
JdbcUtil.close(conn, stmt,rs);
}
}
}


乍一看没什么问题啊,可以识别用户,判断是否登陆成功,但是接下来给大家介绍这样的一个情况:

1)首先引入这样一个概念:sql语句被注入



2)接下来我们稍稍修改下刚才的代码:



3)而PreparedStatement接口则不存在这种问题。

2、PreparedStatement模拟用户登陆:

package sram.login;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import org.junit.Test;

import sram.util.jdbc.JdbcUtil;
/**
* 模拟用户登录效果
*/
public class Demo1{
//模拟用户输入:SELECT * FROM admin WHERE userName='zhangsan' OR 1=1 -- 'AND pwd='123';
private String name = "用户随意输入' OR 1=1 -- ";
private String password = "密码任意";

/**
* Statment存在sql被注入的风险
*/
//public void testByStatement(){}

/**
* PreparedStatement可以有效地防止sql被注入
*/
@Test
public void testByPreparedStatement(){
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
//获取连接
conn = JdbcUtil.getConnection();
String sql = "SELECT * FROM admin WHERE userName=? AND pwd=?";
//预编译
stmt = conn.prepareStatement(sql);
//设置参数
stmt.setString(1, name);
stmt.setString(2, password);
//执行sql
rs = stmt.executeQuery();
if(rs.next()){
//登录成功
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
System.out.println(sql);
System.out.println(stmt);
System.out.println(rs);

} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
JdbcUtil.close(conn, stmt ,rs);
}
}
}


运行结果:



推荐使用PreparedStatement
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息