JDBC 详细笔记:从基础 API 到 SQL 注入解决

本文涵盖JDBC 概述、开发步骤、核心 API、增删改查、工具类封装、SQL 注入漏洞与解决的内容。

一、JDBC 的概述

1. JDBC 是什么

  • JDBC:Java DataBase Connectivity,Java 数据库连接
  • 目的:使用 Java 代码操作数据库
  • 必须遵循 JDBC 规范才能操作数据库

2. JDBC 的规范

  • JDBC 是一套接口规范
  • 实现类由各数据库厂商提供
  • 只需掌握 JDBC 接口与方法即可通用操作数据库

3. 驱动(数据传输桥梁)

  • 驱动就是数据库厂商提供的实现类
  • 使用 MySQL 必须导入驱动 jar 包:mysql-connector-java-5.1.13-bin.jar

4. JDBC 开发入门步骤

  1. 加载驱动
  2. 获取连接
  3. 执行 SQL 语句
  4. 处理结果集(查询)
  5. 释放资源

二、JDBC

1. MySQL 准备:创建数据库与表

复制代码
-- 创建数据库
create database jdbcdemo;
use jdbcdemo;

-- 创建用户表
create table t_user(
id int primary key auto_increment,
username varchar(30),
password varchar(30),
email varchar(30)
);

-- 插入测试数据
insert into t_user values (null,'aaa','123','aaa@163.com');
insert into t_user values (null,'bbb','456','bb@163.com');
insert into t_user values (null,'ccc','789','ccc@163.com');

2. 需求

查询t_user表所有数据并输出到控制台

3. 标准开发步骤

  1. 加载驱动,使用 DriverManager类
  2. 获取连接,返回 Connection 接口,说明连上了数据库的服务器
  3. 编写 SQL 语句
  4. 获取执行 SQL 的对象(Statement 接口)
  5. 查询返回结果封装到 ResultSet接口,遍历结果集
  6. 释放资源(调用 close ())

三、JDBC 相关接口和 API

1. DriverManager 类(驱动管理)

作用
  • 加载驱动
    • static void registerDriver(Driver driver)
    • 参数:传入的真正的参数其实是MySQL 提供 Driver 的类
  • 获取数据库连接
加载驱动
java 复制代码
Class.forName("com.mysql.jdbc.Driver");
  • 不推荐:DriverManager.registerDriver(new Driver())
    • 过度依赖实现类
    • 驱动被加载两次
获取连接
java 复制代码
static Connection getConnection(String url, String user, String password)

URL 格式

java 复制代码
jdbc:mysql://localhost:3306/数据库名
  • jdbc:主协议
  • mysql:子协议
  • localhost:主机地址
  • 3306:MySQL 默认端口
  • 数据库名:要操作的库

本地简写

复制代码
jdbc:mysql:///数据库名

示例:

java 复制代码
Connection conn = DriverManager.getConnection("jdbc:mysql:///jdbcdemo", "root", "root");

2. Connection 接口(数据库连接)

  • 代表数据库连接,资源稀有,用完必须释放
作用
  1. 获取执行 SQL 的对象
    • Statement createStatement() ‐‐ 获取到Statement接口
    • PreparedStatement prepareStatement(String sql)
      ‐‐ 获取到 PreparedStatement 接口,对象非常重要的,防止SQL 注入的漏洞。
  2. 管理事务
    • setAutoCommit(boolean autoCommit):开启事务
    • commit():提交事务
    • rollback():回滚事务

3. Statement 接口(执行 SQL 语句)

  • 用于执行 SQL 语句的对象
方法
  • 查询ResultSet executeQuery(String sql)
  • 增删改int executeUpdate(String sql)
  • 批处理
    • addBatch(String sql):添加 SQL 到批处理
    • clearBatch():清空批处理
    • executeBatch():执行批处理

4. ResultSet 接口(结果集封装)

  • 封装查询返回的表格数据
  • 内部维护游标,默认指向第一行之前
  • 调用next()向下移动游标,移动到某一行,获取该行的数据
  • 游标只能向下移动
获取数据方法
  • 根据类型:getInt()getString()getLong()
  • 通用:getObject()(自行强转)
  • 两种取值方式
    1. getInt(int index) ‐‐ 通过下标值来取值,默认从 1 开始
    2. getInt(String s) ‐‐ 通过字段的名称来取值,比较常用的

5. 释放资源

  • 连接对象必须释放
  • 代码放在finally中保证执行
  • 标准释放模板
java 复制代码
if(conn != null){
    try {
        conn.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    conn = null;
}

四、JDBC 增删改查

  • 目标:回顾 API 方法 + 封装工具类

JDBC 工具类编写步骤

  1. 在 src 目录创建db.properties配置文件(key=value 格式)
  2. 编写工具类加载配置、获取连接、统一释放资源

控制台登录案例步骤

  1. 导入 MySQL 驱动 jar 包
  2. 复制工具类与配置文件
  3. 编写 User 实体类(JavaBean)
  4. 实现登录功能

五、SQL 注入漏洞

1. 漏洞效果

已知用户名,输入任意密码都能登录成功

2. 漏洞产生条件

  • 已知用户名
  • 后台直接字符串拼接 SQL

3. 注入示例

用户名输入:aaa' or '1=1密码任意

拼接后 SQL:

复制代码
select * from t_user where username = 'aaa' or '1=1' and password = 'xxx'

或:

复制代码
aaa' -- '

拼接后注释掉后面条件

java 复制代码
-- 原因
String sql = "select * from t_user where username = '"+username+"' and password =
'"+password+"'";
-- 测试SQL注入漏洞的时候,输入如下的值
aaa'or'1=1,密码任意的
String sql = "select * from t_user where username = 'aaa'or'1=1' and
password = 'sfsdfsds";
aaa'‐‐ ',密码也是任意的
String sql = "select * from t_user where username = 'aaa'‐‐ '' and password
= 'sfsdfsdfs";
-- 实就是拼接SQL语句

4. 解决 SQL 注入

使用PreparedStatement接口(Statement 子接口)

  • 支持预编译 SQL
  • 使用?作为占位符
  • SQL 先编译,再传参,参数不会改变 SQL 结构
步骤
  1. 编写带?的 SQL
java 复制代码
String sql = "select * from t_user where username=? and password=?";
  1. 获取 PreparedStatement
java 复制代码
PreparedStatement pstmt = conn.prepareStatement(sql);
  1. 给?赋值(下标从 1 开始)
java 复制代码
pstmt.setString(1, username);
pstmt.setString(2, password);
  1. 执行(无参数)
  • 查询:pstmt.executeQuery()
  • 增删改:pstmt.executeUpdate()

总结

  1. JDBC 是 Java 操作数据库的规范,由厂商提供驱动实现
  2. 核心 API:DriverManager、Connection、Statement、ResultSet
  3. 开发固定步骤:加载驱动→获取连接→执行 SQL→处理结果→释放资源
  4. Statement 存在 SQL 注入风险,开发优先使用 PreparedStatement
相关推荐
Elastic 中国社区官方博客30 分钟前
如何比较两个 Elasticsearch 索引并找出缺失的文档
大数据·运维·数据库·elasticsearch·搜索引擎
DLYSB_43 分钟前
生命通道:如何用 HIS 医疗系统直连网络声光终端,打造“零延误”的危急值响应网关?
java·网络·数据库·报警灯
儒雅的大叔1 小时前
MySQL数据库InnoDB数据恢复工具使用总结
数据库·mysql·adb
观远数据1 小时前
ChatBI选型对比:从意图识别到SQL修复,六个维度打分决定是否值得投产
数据库·人工智能·sql
嘉&年华1 小时前
【第008篇】通过dexp和dimp命令导出和导入dmp文件(适用于达梦数据库)
数据库·sql
哥是强混3 小时前
Means:基于 .NET 10 打造的开源自部署 S3 兼容对象存储服务
网络·数据库·.net
ffqws_3 小时前
redis面试:如何保证双写一致
数据库·redis·缓存
水无痕simon3 小时前
6 数据库同义词
数据库
Piko6144 小时前
锐捷 VSU 虚拟化堆叠配置
运维·网络·笔记
杜子不疼.4 小时前
【Qt初识】信号槽(三):机制意义、断开连接与 Lambda 表达式
开发语言·数据库·qt