JDBC 极速入门,只要抓住一条主线:用六步把 Java 程序连上数据库、查出数据,再学会用 PreparedStatement 防注入、用事务保证要么全成要么全败、用连接池避免反复建连接。本文面向学过 Java 基础但没碰过数据库的读者,从最朴素的"连上再说"讲起,每一步都配可运行代码。跟着做,你就能在自己的项目里写出第一条不踩坑的数据库访问代码。下面先把"为什么需要 JDBC"用大白话讲清楚。不管你后面是做 Web 后台、做接口服务,还是参加课程项目,只要应用要落地真实数据,JDBC 都是第一道必须跨过的门槛。把这条主线走顺,你写的程序就能真正和数据库对话。

一、为什么 Java 要学 JDBC:程序和数据库的桥梁
你写的 Java 程序跑在内存里,变量、对象用完就丢;而 MySQL 这样的数据库把数据持久地存在磁盘上,关掉程序数据还在。两者本来是两套互不相通的世界,JDBC 就是架在它们之间的桥。JDBC 全称是 Java Database Connectivity,你可以把它理解成 Java 官方定的一套"和数据库对话的统一规矩":不管底层是 MySQL、PostgreSQL 还是 Oracle,只要它提供了 JDBC 驱动,你的 Java 代码就能用同一套写法去连、去查。
为什么不能直接用文件存?因为当数据变成几千几万条、还要支持多人同时读写、还要按条件快速检索时,自己写文件管理会迅速崩溃。数据库帮你把这些问题都解决了,而 JDBC 让你写的 Java 代码能自然地"借力"数据库的能力。所以只要你的 Java 应用需要存点像样的数据,JDBC 就是绕不开的一课。
如果你 Java 基础还不牢,建议先过一遍 Java 教程,把类、对象、异常处理这几个概念理顺,再来学 JDBC 会轻松很多。下面我们直接上手,看一条查询在 JDBC 里到底分几步完成。
二、JDBC 六步:从连上数据库到拿到结果
JDBC 操作数据库有一个几乎固定的六步套路,记住它就记住了骨架:第一步加载驱动,告诉 Java 用哪个数据库的实现;第二步用 DriverManager 建立连接 Connection,相当于拨通数据库的电话;第三步创建 Statement,相当于拿到一个可以"说 SQL"的话筒;第四步用 Statement 执行 SQL 拿到结果集 ResultSet;第五步遍历 ResultSet 把数据取出来;第六步关闭所有资源,避免连接泄漏。
对初学者来说,最容易忘的是第六步。ResultSet、Statement、Connection 这些都不是普通对象,它们背后占着真实的数据库连接和内存,不关掉,连接就会被一点点耗尽,程序跑久了就卡死。所以习惯上要用 try-finally 或 try-with-resources 把关闭动作兜住,哪怕中间出错也能保证资源释放。
// JDBC 六步示意:查出 users 表里所有用户名
Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT username FROM users");
while (rs.next()) {
String name = rs.getString("username");
System.out.println(name);
}
rs.close();
stmt.close();
conn.close();
这段做了什么:连上数据库后创建 Statement,执行一条查询,再用 while 循环把每一行的 username 取出来打印,最后依次关闭三个资源。六步里真正产生业务价值的是第五步的取值,但前四步是把桥搭起来、把话筒拿稳的必要铺垫。把这六步抄熟、跑通一次,JDBC 的门就算进了。
三、PreparedStatement 防注入:别让一句输入掀翻整张表
上面用的 Statement 有个致命隐患:如果你把用户输入直接拼进 SQL 字符串,就给"SQL 注入"开了门。举个例子,登录时拼出 "SELECT * FROM users WHERE name = '" + 用户输入 + "'",攻击者输入一段特殊的字符串,就能让这条语句变成删表或绕过的危险指令。这不是吓唬人,是真实世界里最高频的攻击之一。
解决办法是 PreparedStatement,它先把 SQL 写成带问号的模板,再把参数安全地"填"进去,数据库会严格区分"代码"和"数据",用户输入再怎么构造都不会被当成指令执行。写法上把参数位置用 ? 占位,再用 setString、setInt 这类方法按位置赋值,既安全又清晰,还能借助预编译提升一点性能。
// 用 PreparedStatement 替代字符串拼接,杜绝 SQL 注入
String sql = "SELECT * FROM users WHERE username = ? AND age = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, inputName);
ps.setInt(2, inputAge);
ResultSet rs = ps.executeQuery();
这段做了什么:把 SQL 写成带 ? 的模板,再用 set 方法把用户输入当作纯数据填进去。即使 inputName 里藏着恶意片段,数据库也只会把它当成一个普通字符串去匹配,无法改变 SQL 的结构。写数据库访问代码时,默认就用 PreparedStatement,把 Statement 留给完全不含外部输入的固定语句。写 Java 时如果记不住 PreparedStatement、ResultSet 这些类的用法,Java 速查手册 可以当桌面字典随时翻,边写边查比反复搜索更高效。
四、事务提交与回滚:要么全成要么全败
很多业务不是一条 SQL 能搞定的。比如转账,要从 A 账户扣钱、给 B 账户加钱,这必须是两步。如果扣完 A 之后程序突然报错,B 没加上,钱就凭空消失了。事务就是用来兜住这种场景的:把多条 SQL 包成一个整体,要么全部成功提交,要么一处出错就整体回滚,回到操作前的状态,绝不让数据卡在"做了一半"。
JDBC 里默认每条 SQL 自动提交,这不适合多步操作。你要先调用 setAutoCommit(false) 关掉自动提交,然后正常执行多条语句,全部成功后再 commit() 提交;一旦中间捕获到异常,就调用 rollback() 回滚。这样即便中途失败,数据库也像什么都没发生过一样,保证了数据一致性。
conn.setAutoCommit(false);
try {
stmt.executeUpdate("UPDATE accounts SET money = money - 100 WHERE name = 'A'");
stmt.executeUpdate("UPDATE accounts SET money = money + 100 WHERE name = 'B'");
conn.commit();
} catch (Exception e) {
conn.rollback();
}
这段做了什么:先关闭自动提交,把扣款和加款两步放进同一个事务,都成功才 commit,抛异常就 rollback。事务的精髓就是"全有或全无",它让多步操作在失败时不留半成品。涉及金额、库存、订单状态这类必须一致的场景,务必用事务包起来。
五、连接池为什么必要:别每次请求都重连
前面每个例子都是"现用现连、用完就关",这在练习里没问题,放到真实服务上会出大事。建立一次数据库连接要走网络握手、身份认证,成本很高;如果几百个用户同时访问,每次都新建连接再销毁,数据库很快被压垮,响应也慢得没法用。连接池就是为此而生的。
连接池的思路像"共享充电宝柜":提前建好一批连接放在池子里,谁要用就借一个,用完还回去而不是销毁。这样既省了反复建连的开销,又能控制总连接数、防止把数据库打爆。Java 里常见的连接池组件(如 HikariCP、Druid)都能几行配置接上,你代码里取连接的方式基本不变,只是连接来自池子而非每次新建。
想回顾数据库本身怎么用,可以翻 MySQL 教程 把建库建表那套补齐。把"连接交给池子管"这点刻进习惯,你的应用才扛得住真实流量。

总结
JDBC 极速入门,主线就是四块:用六步把 Java 连上数据库并取数、用 PreparedStatement 替代字符串拼接防注入、用事务把多步操作包成"全成或全败"、用连接池避免每次请求都重建连接。其中防注入和事务是安全与正确性的底线,连接池是性能的上限,四者都吃透,你写的数据库访问代码才既稳又安全。
下一步建议顺着配套路径补强:JDBC极速入门指南是图文微课形式,适合把六步和事务再练扎实;处理查询结果时经常要操作字符串,那篇讲 Java 字符串三种处理方法的笔记能直接套用;而 JDBC 跑的都是 SQL,SQL 教程能帮你把查询语言的整体语法系统学一遍。文末「延伸学习」里放好了对应入口。
延伸学习
想把这块知识系统补齐,可以按这个顺序来:
- 先跟着 JDBC极速入门指南 这套图文微课把六步、事务、连接池完整练一遍;
- 写代码经常要对结果做字符串判断时,参考 Java字符串处理笔记 里的三种常用处理方式;
- JDBC 执行的都是 SQL,深入前补一下 SQL 教程,查询和过滤会写得更顺。
常见问题
Q:Statement 和 PreparedStatement 到底选哪个?
A:只要 SQL 里包含任何外部输入,一律用 PreparedStatement,它是防注入的标准做法。Statement 只适合完全写死、不含变量的固定语句。养成默认用 PreparedStatement 的习惯,能避开一大类安全漏洞。
Q:事务里某一步失败了,前面执行的会保留吗?
A:不会,这正是事务的意义。只要调用了 rollback(),从事务开始到出错前的所有改动都会被撤销,数据库回到事务开始前的一致状态。所以多步写操作一定要用 try-catch 包住,失败时回滚。
Q:连不上数据库一般先查什么?
A:先看四样:URL 里的库名和端口对不对、用户名密码是否正确、数据库服务是否真的在运行、以及驱动包有没有正确引入。多数连不上都是这四类配置问题,逐项核对基本都能解决。

免费 AI IDE



