java连接到数据库代码怎么写
- 数据库
- 2025-08-01
- 2
是关于如何在Java中连接到数据库的详细说明,重点介绍JDBC(Java Database Connectivity)的使用步骤、代码示例及注意事项,文章内容涵盖驱动加载、建立连接、执行SQL语句、处理结果集和资源释放等核心环节,并附有常见问题解答(FAQs)。
Java连接数据库的核心流程
-
加载JDBC驱动程序:通过
Class.forName()
方法将数据库厂商提供的驱动类注册到JVM中,MySQL的驱动类名为com.mysql.cj.jdbc.Driver
,这一步会触发静态初始化块,将实现类添加到DriverManager
的管理列表里,若未正确添加依赖的JAR文件到类路径,会抛出ClassNotFoundException
。 -
构建数据库URL:格式通常为:
jdbc:subprotocol://hostname:port/databasename?params
,以MySQL为例:jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8
,其中参数可指定编码方式、是否启用SSL等配置项,不同数据库的子协议部分需相应调整(如Oracle为thin
)。 -
创建Connection对象:使用
DriverManager.getConnection(url, user, password)
获取物理连接,该对象代表应用程序与数据库之间的会话通道,后续所有操作均基于此展开,建议将用户名、密码等敏感信息存储在配置文件中而非硬编码。 -
选择执行方式:根据需求选用三种Statement类型:
Statement
:直接拼接SQL字符串,适合简单查询但存在SQL注入风险;PreparedStatement
:预编译带占位符(?)的参数化查询,可有效防止注入攻击并提升性能;CallableStatement
:调用存储过程时使用,推荐优先使用PreparedStatement
以确保安全性。
-
处理结果集(ResultSet):对于SELECT类操作,通过循环遍历
ResultSet
逐行读取数据,注意列索引从1开始计数,或通过列名获取值(如rs.getString("columnName")
),及时判断next()
方法返回值以避免空指针异常。 -
关闭资源顺序:遵循“后开先关”原则,依次释放
ResultSet
→Statement
→Connection
,务必在finally
块中完成释放操作,确保异常发生时仍能正确回收资源。
下面是两个具体的实现案例:
案例1:基础版MySQL连接与查询
import java.sql.; public class BasicJDBCExample { public static void main(String[] args) { String url = "jdbc:mysql://localhost:3306/testdb"; String user = "root"; String password = "password"; try { // 1. 加载驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 2. 建立连接 Connection connection = DriverManager.getConnection(url, user, password); // 3. 创建可预处理语句 String sql = "SELECT id, name FROM users WHERE age > ?"; PreparedStatement pstmt = connection.prepareStatement(sql); pstmt.setInt(1, 18); // 设置第一个问号处的参数值 // 4. 执行查询 ResultSet rs = pstmt.executeQuery(); while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); System.out.println("ID: " + id + ", Name: " + name); } // 5. 关闭资源 rs.close(); pstmt.close(); connection.close(); } catch (ClassNotFoundException e) { System.err.println("找不到JDBC驱动!"); e.printStackTrace(); } catch (SQLException e) { System.err.println("数据库操作失败!"); e.printStackTrace(); } } }
案例2:使用DataSource连接池(推荐生产环境)
import javax.sql.DataSource; import com.mysql.cj.jdbc.MysqlDataSource; import java.sql.; public class PooledConnectionExample { public static void main(String[] args) { // 配置数据源属性 MysqlDataSource dataSource = new MysqlDataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/prod_db?useSSL=false"); dataSource.setUser("appuser"); dataSource.setPassword("securepass"); try (Connection connection = dataSource.getConnection()) { String sql = "UPDATE inventory SET stock = stock ? WHERE product_id = ?"; try (PreparedStatement pstmt = connection.prepareStatement(sql)) { pstmt.setInt(1, 5); // 减少库存数量 pstmt.setLong(2, 1001L); // 根据商品ID更新 int affectedRows = pstmt.executeUpdate(); System.out.println("更新了 " + affectedRows + " 条记录"); } } catch (SQLException e) { System.err.println("事务处理异常!"); e.printStackTrace(); } } }
关键注意事项对比表
项目 | 传统DriverManager方式 | DataSource连接池方式 |
---|---|---|
性能开销 | 每次新建连接 | 复用已存在的空闲连接 |
资源管理 | 需手动关闭所有对象 | 支持try-with-resources自动关闭 |
适用场景 | 开发测试 | 高并发生产环境 |
额外功能 | 无 | 连接超时控制、最大等待队列等 |
相关问答FAQs
Q1: 为什么推荐使用PreparedStatement而不是普通的Statement?
A: 因为PreparedStatement具有三大优势:①预编译机制提高重复执行效率;②强制参数化传输防止SQL注入攻击;③支持批量操作(Batch Update),当用户输入包含单引号的特殊字符时,直接拼接SQL会导致语法错误或安全破绽,而参数化查询会自动转义特殊字符。
Q2: 如果遇到“通信链接失败”的错误应该怎么排查?
A: 按以下顺序检查:①确认数据库服务是否启动并监听正确端口(默认MySQL是3306);②验证URL中的IP地址/域名是否可达(可用ping测试);③检查防火墙是否阻止了对应端口;④确保数据库用户有远程访问权限;⑤查看驱动版本与数据库服务器版本的兼容性(如MySQL 8.0+需使用新版