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'
相关推荐
Shely201728 分钟前
MySQL数据表管理
数据库·mysql
爬山算法35 分钟前
MongoDB(80)如何在MongoDB中使用多文档事务?
数据库·python·mongodb
APguantou41 分钟前
NCRE-三级数据库技术-第2章-需求分析
数据库·需求分析
寂夜了无痕1 小时前
MySQL 主从延迟全链路根因诊断与破局法则
数据库·mysql·mysql主从延迟
爱丽_1 小时前
分页为什么越翻越慢:offset 陷阱、seek 分页与索引排序优化
数据库·mysql
APguantou1 小时前
NCRE-三级数据库技术-第12章-备份与数据库恢复
数据库·sqlserver
Bat U1 小时前
MySQL数据库|表设计+新增+分组查询
数据库·mysql
麦聪聊数据2 小时前
企业数据流通与敏捷API交付实战(五):异构数据跨库联邦与零代码发布
数据库·sql·低代码·restful
Elastic 中国社区官方博客2 小时前
当 TSDS 遇到 ILM:设计不会拒绝延迟数据的时间序列数据流
大数据·运维·数据库·elasticsearch·搜索引擎·logstash
Omics Pro2 小时前
虚拟细胞:开启HIV/AIDS治疗新纪元的关键?
大数据·数据库·人工智能·深度学习·算法·机器学习·计算机视觉