3.Statement对象概述,以及Statement的弊端

Statement对象

1. 概述

在java.sql包中有三个接口分别定义了对数据库的调用的不同方式:

  • Statement:用于执行静态sql语句并返回结果
  • PreparedStatement:sql语句被预编译并存储在此对象中,可以使用此对象多次高效的执行该sql语句;
  • CallableStatement:用于执行存储过程。

2. Statement和PreparedStatement 的区别

  1. PreparedStatement 是 Statement的子类;
  2. Statement 是sql拼串,有sql注入的问题;
  3. PreparedStatement ,使用sql预编译,随后再填充占位符,解决了sql注入的问题;
  4. PreparedStatement 可以操作Blob类型的数据;
  5. PreparedStatement 可以批量操作;

3. Statement的弊端(sql注入攻击)

接下来用一个例子演示,数据表如下

java 复制代码
public class StatementTest {

    @Test
    public void test() throws Exception {
        Connection connection = JDBCUtils.getConnection();

        Statement statement = connection.createStatement();

        String username = "AA";
        String password = "123456";
        String sql = "SELECT user,password,balance FROM user_table WHERE USER = '" + username + "' AND PASSWORD = '" + password + "'";

        ResultSet resultSet = statement.executeQuery(sql);

        while (resultSet.next()) {

            String user = resultSet.getString(1);
            String pwd = resultSet.getString(2);

            User user1 = new User(user, pwd);
            System.out.println(user1);

        }

        JDBCUtils.close(connection,statement);
    }
}

可以成功查询到数据:

java 复制代码
User{user='AA', password='123456', balance=1000}

但是如果修改一下输入信息:

java 复制代码
String username = "1' or ";
String password = " ='1' or '1' = '1";
java 复制代码
public class StatementTest {

    @Test
    public void test() throws Exception {
        Connection connection = JDBCUtils.getConnection();

        Statement statement = connection.createStatement();

        String username = "1' or ";
        String password = " ='1' or '1' = '1";
        String sql = "SELECT user,password,balance FROM user_table WHERE USER = '" + username + "' AND PASSWORD = '" + password + "'";
        
        ResultSet resultSet = statement.executeQuery(sql);

        while (resultSet.next()) {

            String user = resultSet.getString(1);
            String pwd = resultSet.getString(2);
            int balance = resultSet.getInt(3);

            User user1 = new User(user, pwd, balance);
            System.out.println(user1);

        }

        JDBCUtils.close(connection,statement);
    }
}

输出结果:将所有数据都查出来了

java 复制代码
User{user='AA', password='123456', balance=1000}
User{user='BB', password='654321', balance=1000}
User{user='CC', password='abcd', balance=2000}
User{user='DD', password='abcder', balance=3000}

相当于执行了以下sql

sql 复制代码
SELECT user,password,balance FROM user_table WHERE USER = '1' or ' AND PASSWORD = ' ='1' or '1' = '1'
相关推荐
wljt11 小时前
Redis的5种数据类型
数据库·redis·缓存
sakiko_12 小时前
Swift学习笔记30-数据库SQlite语句
数据库·学习·swift
IvorySQL12 小时前
用生成列提升 JSONB 查询效率:PostgreSQL 三种索引方案实测对比
数据库·postgresql
STDD12 小时前
Abiotic Factor多人生存建筑游戏《非生物因素》 专用服务器搭建教程
服务器·数据库·游戏
淼淼爱喝水12 小时前
【Ansible 入门实战】三种变量详解
java·linux·数据库·ansible·playbook
云草桑12 小时前
Odoo企业商用到底是不是免费的?
数据库·odoo·erp
燕-孑12 小时前
redis详解-进阶
数据库·redis·缓存
BGD1045017312 小时前
datagear(7)-期末作业:综合数据分析
数据库·数据分析
Hoxy.R12 小时前
百家争鸣下的 Vastbase G100:一次国产数据库体验与思考
数据库
gf132111112 小时前
python_更新飞书多维表格的单项关联字段
数据库·python·飞书