微软官方推荐使用的 Java 驱动是 Microsoft JDBC Driver for SQL Server,它功能强大、性能优越,并且由微软官方持续更新和维护,是生产环境中的首选。
驱动类型与历史
在 Java 世界中,数据库连接遵循 JDBC (Java Database Connectivity) 规范,SQL Server 的驱动主要有两种:
a) Microsoft JDBC Driver (官方推荐,当前标准)
这是微软官方开发和维护的驱动,也是目前唯一推荐使用的驱动,它经历了几个主要版本,每个版本都有其特点:
-
JDBC Driver 6.0, 6.2, 6.4 (较旧版本)
- 这些版本已经过时,不再推荐用于新项目。
- 它们支持 Java 6, 7, 8 等较旧的 JDK 版本。
- 如果你维护的旧系统仍在使用,可以继续使用,但应考虑升级。
-
JDBC Driver 7.0 (主流版本)
- 重要特性: 引入了 mssql-jdbc 包名。
- JDK 要求: 需要 Java 8 (JDK 8) 或更高版本。
- 模块化: 支持 Java 9 的模块系统 (JPMS)。
- 性能: 包含性能优化和新的功能,如 Always Encrypted 支持的改进。
- 这是目前大多数生产环境正在使用的稳定版本。
-
JDBC Driver 12.0 (最新版本)
- 重要特性: 继续使用 mssql-jdbc 包名。
- JDK 要求: 需要 Java 11 (JDK 11) 或更高版本。
- 兼容性: 对新版 Java (如 Java 17, 21) 提供了最佳支持。
- 功能: 引入了针对 Azure SQL 和新版 SQL Server 的功能,以及对 Azure Active Directory (Azure AD) 身份验证的增强支持。
- 强烈建议 在新项目中使用此版本或更高版本。
b) jTDS (第三方开源驱动)
- 来源: 由一个社区团队维护的开源驱动。
- 特点: 曾经非常流行,以其高性能和轻量级著称。
- 现状: 不再推荐使用,它已经多年没有重大更新,不支持最新的 SQL Server 功能(如 Always Encrypted、最新的身份验证方式等),也不兼容新版 JDK,仅适用于无法迁移的遗留系统。
请始终选择 Microsoft JDBC Driver,根据你的 JDK 版本和项目需求,在 7.0 或 12.0 之间选择。
如何获取和添加驱动 (Maven/Gradle)
最简单、最推荐的方式是通过 Maven 或 Gradle 等构建工具来管理依赖。
使用 Maven
在你的 pom.xml 文件中添加对应版本的依赖。
对于 JDBC Driver 12.0 (推荐):
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<!--
请访问 Maven Central 查找最新版本
当前最新版本可能是 12.6.1.jre11 或更高
-->
<version>12.6.1.jre11</version>
<!--
scope=runtime 表示它只在运行时需要,编译和测试时不需要
这是最佳实践
-->
<scope>runtime</scope>
</dependency>
对于 JDBC Driver 7.0:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>7.4.1.jre8</version> <!-- 示例版本,请查找最新版 -->
<scope>runtime</scope>
</dependency>
使用 Gradle
在你的 build.gradle 或 build.gradle.kts 文件中添加依赖。
对于 JDBC Driver 12.0 (推荐):
// build.gradle
implementation 'com.microsoft.sqlserver:mssql-jdbc:12.6.1.jre11'
// build.gradle.kts (Kotlin DSL)
implementation("com.microsoft.sqlserver:mssql-jdbc:12.6.1.jre11")
对于 JDBC Driver 7.0:
// build.gradle
implementation 'com.microsoft.sqlserver:mssql-jdbc:7.4.1.jre8'
// build.gradle.kts (Kotlin DSL)
implementation("com.microsoft.sqlserver:mssql-jdbc:7.4.1.jre8")
注意: 版本号中的
jre11或jre8表示该 JAR 文件是为对应 Java 运行时环境打包优化的,确保你选择的版本与你项目使用的 JDK 版本匹配。
如何在代码中使用
JDBC 的基本使用流程是固定的:加载驱动 -> 获取连接 -> 创建语句 -> 执行查询 -> 处理结果 -> 关闭资源。
下面是一个完整的示例代码,展示了如何连接到 SQL Server 并执行查询。
示例代码 (JDBC Driver 7.0/12.0)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class SqlServerJdbcExample {
// 数据库连接信息 - 请根据你的实际情况修改
// JDBC URL 格式: jdbc:sqlserver://[serverName][:port][;databaseName=<dbName>][;property1=value1;...]
private static final String DB_URL = "jdbc:sqlserver://localhost:1433;databaseName=YourDatabase;encrypt=false;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);
PreparedStatement pstmt = conn.prepareStatement("SELECT id, name, email FROM users WHERE id = ?");
ResultSet rs = pstmt.executeQuery()) {
// 设置 PreparedStatement 的参数
pstmt.setInt(1, 1); // 查询 id 为 1 的用户
System.out.println("Connection to SQL Server successful!");
// 遍历结果集
while (rs.next()) {
// 通过列名获取数据,更具可读性且不易受列顺序影响
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email);
}
} catch (SQLException e) {
// 处理 SQL 异常
System.err.println("Database connection or query failed!");
e.printStackTrace();
}
}
}
代码解析
-
JDBC URL:
jdbc:sqlserver://: 协议头,表示使用 SQL Server JDBC 驱动。localhost:1433: 服务器地址和端口,如果你的 SQL Server 在不同机器或使用不同端口,请修改。databaseName=YourDatabase: 指定要连接的数据库。encrypt=false;trustServerCertificate=true;: 这两个参数在本地开发或测试时非常常用。encrypt=false: 不加密连接(对于本地测试可以接受)。trustServerCertificate=true: 信任服务器提供的 SSL 证书,即使它不是由受信任的颁发机构签发的。在生产环境中,你应该配置正确的 SSL 证书,而不是简单地信任所有证书。
-
DriverManager.getConnection(): 这是建立数据库连接的核心方法,它会自动在类路径中查找已注册的 JDBC 驱动(通过 Maven/Gradle 依赖引入的驱动会自动注册)。 -
PreparedStatement: 强烈推荐使用PreparedStatement而不是Statement。- 安全性: 可以有效防止 SQL 注入攻击。
- 性能: 对于需要多次执行的 SQL(仅参数不同),数据库可以预编译,提高执行效率。
-
try-with-resources: 这是一个 Java 7+ 的特性,可以自动实现AutoCloseable接口的对象(如Connection,Statement,ResultSet)在代码块结束时自动关闭,从而避免资源泄漏。
常见问题与最佳实践
-
ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver- 原因: Java 虚拟机在运行时找不到 SQL Server 的驱动类。
- 解决方案: 确保 Maven/Gradle 依赖已正确添加,并且项目已成功重新构建(刷新依赖),检查生成的
target或build目录中是否包含了mssql-jdbc-xxx.jar文件。
-
The TCP/IP connection to the host has failed- 原因: 无法连接到 SQL Server 服务器。
- 检查清单:
- SQL Server 服务是否正在运行?
- 服务器地址 (
localhost) 和端口号 (1433) 是否正确? - 防火墙是否阻止了 1433 端口的连接?
- SQL Server 配置为仅允许特定协议(如 Named Pipes),确保你的 JDBC URL 或服务器配置与之匹配。
-
Login failed for user '...'- 原因: 用户名或密码错误,或者该用户没有访问指定数据库的权限。
- 解决方案: 检查用户名和密码是否正确,可以使用 SQL Server Management Studio (SSMS) 先登录验证一下,检查用户在目标数据库上的
db_owner或其他适当角色权限。
-
连接池 (Connection Pooling)
- 在生产环境中,绝对不要每次请求都创建和销毁连接,这性能开销巨大。
- 应该使用连接池来管理数据库连接,常用的连接池库有:
- HikariCP: 目前性能最好的连接池,是 Spring Boot 2.x 的默认选择。
- Apache DBCP
- c3p0
- 你可以将 HikariCP 与 JDBC Driver 结合使用,创建一个高效的数据库访问层。
-
JDK 版本兼容性
务必确保你下载的 JDBC Driver 版本与你项目使用的 JDK 版本兼容,JDBC Driver 12.0 需要 JDK 11+,而 7.0 需要 JDK 8+,不兼容会导致运行时错误。
