我们将主要介绍使用 JDBC (Java Database Connectivity) 的方式,这是 Java 连接数据库的标准方法。

核心步骤
无论使用哪种数据库,通过 JDBC 连接数据库的基本步骤都是相同的:
- 加载 JDBC 驱动:将数据库厂商提供的 JDBC 驱动程序加载到 JVM 中。
- 建立数据库连接:使用
DriverManager类和数据库的 URL、用户名、密码来获取一个Connection对象。 - 创建执行语句:通过
Connection对象创建Statement或PreparedStatement对象,用于执行 SQL 语句。 - 执行 SQL 查询并处理结果:执行查询,获取
ResultSet对象,然后遍历结果集,处理数据。 - 关闭资源:按照
ResultSet->Statement->Connection的顺序,关闭所有打开的资源,以释放数据库连接和内存。
使用 JDBC 驱动 JAR 文件(传统方式)
这是最经典的方式,需要手动下载并管理 JDBC 驱动 JAR 文件。
准备工作
-
下载 JDBC 驱动:
- 访问 Microsoft 官方下载页面:Microsoft JDBC Drivers for SQL Server
- 选择与您的 Java 版本和 SQL Server 版本匹配的驱动程序下载。
- 下载后,解压压缩包,找到
mssql-jdbc-<version>.jar文件。
-
配置项目:
(图片来源网络,侵删)- 在 IDE (如 IntelliJ IDEA 或 Eclipse) 中:将下载的
.jar文件添加到项目的类路径中。- IntelliJ IDEA: 右键项目 ->
Open Module Settings->Libraries-> ->Java,然后选择.jar文件。 - Eclipse: 右键项目 ->
Build Path->Configure Build Path->Libraries->Add External JARs...,然后选择.jar文件。
- IntelliJ IDEA: 右键项目 ->
- 使用 Maven:如果使用 Maven,可以直接在
pom.xml中添加依赖,这是更推荐的方式(见场景二)。
- 在 IDE (如 IntelliJ IDEA 或 Eclipse) 中:将下载的
完整代码示例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcSqlServerExample {
// 数据库连接信息
// 请根据您的实际情况修改这些值
private static final String DB_URL = "jdbc:sqlserver://localhost:1433;databaseName=YourDatabaseName;encrypt=true;trustServerCertificate=true;";
private static final String USER = "your_username";
private static final String PASS = "your_password";
public static void main(String[] args) {
// 使用 try-with-resources 语句自动关闭资源
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS)) {
System.out.println("连接数据库成功!");
// --- 示例1:执行查询 ---
queryData(conn);
// --- 示例2:执行插入 ---
insertData(conn, "John Doe", "john.doe@example.com");
} catch (SQLException e) {
System.err.println("连接数据库失败!");
e.printStackTrace();
}
}
/**
* 查询数据示例
*/
private static void queryData(Connection conn) throws SQLException {
String sql = "SELECT id, name, email FROM users";
// 使用 try-with-resources 确保 Statement 和 ResultSet 被关闭
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
System.out.println("\n--- 查询用户列表 ---");
while (rs.next()) {
// 通过列名获取数据,更安全且可读性高
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
System.out.println("ID: " + id + ", 姓名: " + name + ", 邮箱: " + email);
}
}
}
/**
* 插入数据示例 (使用 PreparedStatement 防止 SQL 注入)
*/
private static void insertData(Connection conn, String name, String email) throws SQLException {
// 使用 ? 作为占位符
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
// try-with-resources 确保 PreparedStatement 被关闭
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 设置参数
pstmt.setString(1, name);
pstmt.setString(2, email);
// 执行更新
int affectedRows = pstmt.executeUpdate();
System.out.println("\n--- 插入数据成功,影响了 " + affectedRows + " 行。 ---");
}
}
}
代码详解
-
DB_URL:jdbc:sqlserver://: 协议和子协议。localhost:1433: 数据库服务器的地址和端口,SQL Server 在远程,请替换为相应的 IP 地址或域名。databaseName=YourDatabaseName: 要连接的数据库名称。encrypt=true;trustServerCertificate=true;: 这是现代 SQL Server 的推荐设置,用于加密连接。trustServerCertificate=true表示客户端信任服务器证书(在开发环境中很方便,生产环境应配置正确的证书)。
-
DriverManager.getConnection(...): 这是建立连接的核心方法。 -
StatementvsPreparedStatement:Statement: 用于执行静态 SQL 语句。注意:不要使用Statement来拼接用户输入的 SQL,这极易导致 SQL 注入攻击。PreparedStatement: 用于执行预编译的 SQL 语句,它使用 作为参数占位符,可以有效地防止 SQL 注入,并且对于需要多次执行的 SQL(仅参数不同)性能更高。在所有涉及用户输入或变量的 SQL 操作中,都应优先使用PreparedStatement。
-
try-with-resources: Java 7 引入的语法,可以自动实现AutoCloseable接口的资源的关闭(如Connection,Statement,ResultSet),这是最佳实践,可以避免资源泄漏。
(图片来源网络,侵删)
使用 Maven 管理依赖(推荐方式)
在现代 Java 项目中,使用 Maven 或 Gradle 等构建工具来管理依赖是标准做法。
配置 pom.xml
在您的 Maven 项目的 pom.xml 文件中,添加以下依赖:
<dependencies>
<!-- Microsoft JDBC Driver for SQL Server -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>11.2.1.jre8</version> <!-- 请使用最新版本 -->
</dependency>
</dependencies>
添加后,Maven 会自动下载并配置好驱动,您无需手动添加 JAR 文件。
代码
代码本身与场景一完全相同,因为 Maven 已经将驱动类加载到类路径中了。
使用连接池(生产环境必备)
在 Web 应用等高并发场景下,频繁地创建和销毁数据库连接会带来巨大的性能开销,连接池(Connection Pool)应运而生,它预先创建一组数据库连接,并将它们存放在池中,应用程序需要时从中获取,使用完毕后再放回池中,而不是关闭。
HikariCP 是目前性能最好的 Java 连接池实现。
配置 pom.xml (添加 HikariCP 依赖)
<dependencies>
<!-- Microsoft JDBC Driver for SQL Server -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>11.2.1.jre8</version>
</dependency>
<!-- HikariCP 连接池 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version> <!-- 请使用最新版本 -->
</dependency>
</dependencies>
使用 HikariCP 的代码示例
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class HikariCPExample {
private static HikariDataSource dataSource;
// 静态代码块,在类加载时初始化连接池
static {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:sqlserver://localhost:1433;databaseName=YourDatabaseName;encrypt=true;trustServerCertificate=true;");
config.setUsername("your_username");
config.setPassword("your_password");
// 连接池配置 (可根据实际情况调整)
config.setDriverClassName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
config.setMaximumPoolSize(10); // 最大连接数
config.setMinimumIdle(5); // 最小空闲连接数
config.setConnectionTimeout(30000); // 连接超时时间 (毫秒)
config.setIdleTimeout(600000); // 空闲连接超时时间 (毫秒)
config.setMaxLifetime(1800000); // 连接最大存活时间 (毫秒)
dataSource = new HikariDataSource(config);
}
public static void main(String[] args) {
// 从连接池获取一个连接
try (Connection conn = dataSource.getConnection()) {
System.out.println("从连接池成功获取连接!");
// 执行查询
String sql = "SELECT COUNT(*) FROM users";
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
if (rs.next()) {
int count = rs.getInt(1);
System.out.println("用户总数: " + count);
}
}
} catch (SQLException e) {
System.err.println("获取连接失败!");
e.printStackTrace();
}
// 注意:在 try-with-resources 中,连接会在块结束时自动放回连接池,而不是关闭。
}
}
总结与最佳实践
- 使用构建工具:始终使用 Maven 或 Gradle 来管理 JDBC 驱动依赖,避免手动管理 JAR 文件。
- 优先使用
PreparedStatement:为了安全性和性能,所有动态 SQL 都应使用PreparedStatement。 - 使用
try-with-resources:确保所有 JDBC 资源(Connection,Statement,ResultSet)都能被正确关闭,防止资源泄漏。 - 在生产环境中使用连接池:对于任何非 trivial 的应用,都应使用 HikariCP 等连接池来管理数据库连接,这是性能和稳定性的关键。
- 配置 SSL/TLS:对于生产环境,数据库连接应启用加密,并配置正确的 SSL 证书,而不是简单地使用
trustServerCertificate=true。 - 不要硬编码凭据:不要将数据库用户名和密码直接写在代码中,应使用环境变量、配置文件(如
application.properties)或专门的密钥管理服务来管理敏感信息。
