Connection 是 Java 数据库连接的核心,它代表了 Java 应用程序与特定数据库之间的一个活动会话,你可以把它想象成是应用程序和数据库之间的一条“电话线”,通过这条线路,双方可以互相发送指令和数据。

Connection 对象位于 java.sql 包中(在 JDBC 4.0 之后,也位于 javax.sql 包中)。
Connection 的核心作用
一个 Connection 对象主要承担以下几个关键职责:
-
创建执行 SQL 语句的对象:
- 通过
connection.createStatement()可以创建一个Statement对象,用于执行不带参数的简单 SQL。 - 通过
connection.prepareStatement()可以创建一个PreparedStatement对象,用于执行带参数的预编译 SQL,这是防止 SQL 注入的最佳实践。 - 通过
connection.prepareCall()可以创建一个CallableStatement对象,用于执行数据库存储过程。
- 通过
-
管理事务:
(图片来源网络,侵删)Connection是事务的管理单元,你可以通过它来设置事务的隔离级别(setTransactionIsolation())、提交事务(commit())或回滚事务(rollback())。- 默认情况下,JDBC 的连接是自动提交模式,这意味着每一条
executeUpdate()执行后,数据库会立即自动提交,在需要进行多步操作的业务逻辑中(如银行转账),必须关闭自动提交,手动控制事务。
-
获取数据库的元数据:
- 通过
connection.getMetaData()方法,可以获取一个DatabaseMetaData对象,该对象包含了关于数据库本身的信息,如数据库版本、支持的 SQL 语法、表名、列名等。
- 通过
-
管理连接本身:
- 通过
connection.close()方法,可以显式地关闭数据库连接,将其释放回连接池(如果使用了连接池)或直接关闭底层套接字。
- 通过
如何获取 Connection 对象?
获取 Connection 的标准步骤如下:
步骤 1:加载 JDBC 驱动
在 JDBC 4.0 (Java 6) 之前,需要手动加载驱动类,JDBC 规范要求驱动实现者使用 Service Provider Mechanism,驱动会自动注册,所以这一步通常是可选的。

// 旧式方法,现代JDBC中通常不需要
// Class.forName("com.mysql.cj.jdbc.Driver");
步骤 2:提供数据库连接 URL
这是一个字符串,用于定位数据库,其格式通常为:
jdbc:子协议://主机名:端口号/数据库名
- MySQL:
jdbc:mysql://localhost:3306/mydb - PostgreSQL:
jdbc:postgresql://localhost:5432/mydb - Oracle:
jdbc:oracle:thin:@localhost:1521:orcl - SQL Server:
jdbc:sqlserver://localhost:1433;databaseName=mydb
步骤 3:获取 Connection 对象
使用 DriverManager 类的静态方法 getConnection() 来建立连接。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class BasicConnectionExample {
// 数据库URL、用户名和密码
static final String DB_URL = "jdbc:mysql://localhost:3306/your_database";
static final String USER = "your_username";
static final String PASS = "your_password";
public static void main(String[] args) {
Connection conn = null;
try {
// 1. (可选) 加载驱动
// Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 获取连接
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
System.out.println("Connection successful!");
} catch (SQLException e) {
System.out.println("Connection failed!");
e.printStackTrace();
} finally {
// 3. 关闭连接
if (conn != null) {
try {
conn.close();
System.out.println("Connection closed.");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
Connection 的最佳实践
直接使用 DriverManager 来管理连接在现代应用中是不推荐的,因为它效率低下且无法有效管理连接资源,最佳实践是使用连接池。
为什么需要连接池?
- 性能提升:创建和销毁数据库连接是一个非常耗时和消耗资源的操作,连接池在应用启动时预先创建一组连接,应用程序需要时从池中“借用”,用完后“归还”,避免了频繁创建和销毁的开销。
- 资源管理:可以限制应用同时打开的连接数量,防止数据库因连接过多而崩溃。
- 稳定性:提供了连接的自动回收、检测和重连机制。
如何使用连接池?
-
选择连接池实现:
- HikariCP: 目前性能最好、最流行的连接池,是 Spring Boot 2.x 的默认选择。
- Apache DBCP: Apache 下的经典连接池。
- C3P0: 另一个老牌的连接池实现。
-
配置连接池:通常通过配置文件(如
application.properties或yaml)来设置连接池参数。 -
获取
Connection:从连接池中获取Connection对象,用法和从DriverManager获取基本一致。
示例(使用 HikariCP 和 Spring Boot 的 application.properties)
# application.properties spring.datasource.url=jdbc:mysql://localhost:3306/your_database spring.datasource.username=your_username spring.datasource.password=your_password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # HikariCP 配置 spring.datasource.hikari.connection-timeout=30000 spring.datasource.hikari.maximum-pool-size=10 spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.idle-timeout=600000 spring.datasource.hikari.max-lifetime=1800000
在 Spring Boot 应用中,你只需要注入 DataSource,然后通过它获取 Connection:
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyRepository {
@Autowired
private DataSource dataSource; // Spring Boot 会自动配置好 HikariCP 的 DataSource
public void doSomething() {
Connection conn = null;
try {
// 从连接池中获取一个连接
conn = dataSource.getConnection();
System.out.println("Got connection from pool: " + conn);
// ... 执行数据库操作 ...
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 将连接归还给连接池,而不是关闭它!
if (conn != null) {
try {
conn.close(); // 对于连接池,close() 是归还操作
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
事务管理示例
事务是保证数据一致性的关键,下面是一个手动管理事务的例子。
场景:从账户 A 转账 100 元到账户 B。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TransactionExample {
static final String DB_URL = "jdbc:mysql://localhost:3306/your_database";
static final String USER = "your_username";
static final String PASS = "your_password";
public static void transferMoney(int fromAccountId, int toAccountId, double amount) {
Connection conn = null;
try {
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 关闭自动提交,开启事务
conn.setAutoCommit(false);
// SQL 语句
String sql1 = "UPDATE accounts SET balance = balance - ? WHERE id = ?";
String sql2 = "UPDATE accounts SET balance = balance + ? WHERE id = ?";
// 创建 PreparedStatement
PreparedStatement pstmt1 = conn.prepareStatement(sql1);
PreparedStatement pstmt2 = conn.prepareStatement(sql2);
// 设置参数
pstmt1.setDouble(1, amount);
pstmt1.setInt(2, fromAccountId);
pstmt2.setDouble(1, amount);
pstmt2.setInt(2, toAccountId);
// 执行更新
int rowsAffected1 = pstmt1.executeUpdate();
int rowsAffected2 = pstmt2.executeUpdate();
// 检查两条 SQL 是否都成功执行
if (rowsAffected1 > 0 && rowsAffected2 > 0) {
// 提交事务
conn.commit();
System.out.println("Transfer successful!");
} else {
// 回滚事务
conn.rollback();
System.out.println("Transfer failed, transaction rolled back.");
}
} catch (SQLException e) {
// 发生异常,回滚事务
if (conn != null) {
try {
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
e.printStackTrace();
} finally {
if (conn != null) {
try {
// 恢复自动提交(可选,但推荐)
conn.setAutoCommit(true);
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
| 特性 | 描述 |
|---|---|
| 是什么 | 代表 Java 应用与数据库的一个活动会话。 |
| 核心作用 | 创建 Statement/PreparedStatement、管理事务、获取元数据。 |
| 如何获取 | DriverManager.getConnection() 或从 DataSource(连接池)获取。 |
| 最佳实践 | 必须使用连接池(如 HikariCP)来管理 Connection,而不是直接使用 DriverManager。 |
| 事务管理 | 通过 setAutoCommit(false) 开启事务,commit() 提交,rollback() 回滚。 |
| 资源释放 | 必须在 finally 块中调用 connection.close() 来关闭连接(归还给连接池)。 |
理解并正确使用 Connection 是进行 Java 数据库编程的基础和关键。
