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'
相关推荐
l1t22 分钟前
DeepSeek总结的DuckLake 架构深度剖析-2
数据库·架构
YOU OU33 分钟前
Redis事务
数据库·redis·缓存
数智化管理手记1 小时前
财务大数据怎么管住资金风险?财务大数据和财务数智化到底怎么结合?
大数据·网络·数据库·人工智能·数据挖掘
晓子文集1 小时前
Tushare接口文档:指数成分和权重(index_weight)
大数据·数据库·python·金融·量化投资
吴声子夜歌1 小时前
MongoDB 4.2——入门指南
数据库·mongodb
吴声子夜歌1 小时前
MongoDB 4.x——高可靠
数据库·mongodb
light blue bird2 小时前
组轴式执行引擎 ✅ 多线程调度组装组件
数据库·信息可视化·oracle·桌面端winform·多节点端·gdi图表绘制开发
码农学院2 小时前
Node.js MongoDB构建户外用品GEO优化内容管理平台
数据库·mongodb·node.js
吴声子夜歌2 小时前
MongoDB 4.x——治理经验
数据库·mongodb
黄华SJ520it3 小时前
门店预约系统开发:提升服务行业数字化转型
前端·数据库·系统开发