核心概念
Java 应用程序不能直接与数据库通信,它需要一个“桥梁”或“翻译官”,这个桥梁就是 JDBC (Java Database Connectivity) 驱动程序,对于 SQL Server,这个驱动程序由 Microsoft 提供。

第一步:准备工作
在开始编写代码之前,请确保你已经完成了以下准备工作:
-
安装 SQL Server 数据库
- 确保你的 SQL Server 实例正在运行,并且你知道它的连接信息。
- 你需要知道:
- 服务器名称 (Server Name): 通常是
localhost或0.0.1(如果你在本地安装),或者服务器的 IP 地址/计算机名。 - 端口号 (Port Number): 默认是
1433。 - 数据库名称 (Database Name): 你要连接的数据库。
- 用户名 (Username) 和 密码 (Password): 用于登录数据库的凭据。
- 服务器名称 (Server Name): 通常是
-
安装 Java 开发环境
确保你已经安装了 JDK (Java Development Kit)。
(图片来源网络,侵删) -
获取 SQL Server JDBC 驱动
- 这是连接的关键,你需要下载 Microsoft 提供的 JDBC 驱动 JAR 包。
- 下载地址: Microsoft JDBC Driver for SQL Server
- 如何选择: 根据你的 JDK 版本和 SQL Server 版本选择合适的驱动,最新版的 JDBC 驱动能很好地支持旧版的 SQL Server。
- 下载后: 将下载的
.jar文件添加到你的 Java 项目的类路径 中。
第二步:配置项目(以 Maven 为例)
在现代 Java 开发中,我们通常使用构建工具(如 Maven 或 Gradle)来管理依赖,这是推荐的方式,可以避免手动管理 JAR 包。
使用 Maven (pom.xml)
在你的 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,你需要:
- 从官网下载 JDBC 驱动的 JAR 文件(
mssql-jdbc-11.2.1.jre8.jar)。 - 在你的 IDE(如 IntelliJ IDEA 或 Eclipse)中,将此 JAR 文件添加到项目的库路径中。
- IntelliJ IDEA:
File->Project Structure->Modules->Dependencies-> ->JARs or directories... - Eclipse: 右键项目 ->
Build Path->Configure Build Path->Libraries->Add External JARs...
- IntelliJ IDEA:
第三步:编写 Java 连接代码
下面是一个完整的、可运行的 Java 示例,它演示了如何连接到 SQL Server、执行查询并处理结果。
基本连接和查询示例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SqlServerConnector {
// 数据库连接信息 - 请根据你的实际情况修改
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);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 'Hello, SQL Server!' as Message")) {
// 检查连接是否成功
if (conn != null) {
System.out.println("连接到 SQL Server 成功!");
}
// 处理查询结果
while (rs.next()) {
// 通过列名获取数据,更安全且不易出错
String message = rs.getString("Message");
System.out.println(message);
}
} catch (SQLException e) {
// 捕获并打印 SQL 异常
System.err.println("连接数据库失败!");
e.printStackTrace();
}
}
}
使用 PreparedStatement(推荐用于执行参数化查询)
为了防止 SQL 注入和提高性能,强烈建议使用 PreparedStatement 来执行带参数的查询。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class PreparedStatementExample {
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) {
String sql = "SELECT * FROM Employees WHERE Department = ? AND Salary > ?";
try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 创建 PreparedStatement 对象
PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 设置参数 (索引从 1 开始)
pstmt.setString(1, "IT"); // 第一个 ? 替换为 'IT'
pstmt.setDouble(2, 8000.00); // 第二个 ? 替换为 8000.00
// 执行查询
try (ResultSet rs = pstmt.executeQuery()) {
System.out.println("查询结果:");
while (rs.next()) {
// 假设表中有 ID, Name, Department, Salary 列
int id = rs.getInt("ID");
String name = rs.getString("Name");
String department = rs.getString("Department");
double salary = rs.getDouble("Salary");
System.out.printf("ID: %d, Name: %s, Dept: %s, Salary: %.2f%n", id, name, department, salary);
}
}
} catch (SQLException e) {
System.err.println("执行查询失败!");
e.printStackTrace();
}
}
}
第四步:连接字符串详解
连接字符串是连接数据库的关键,下面详细解释一下:
jdbc:sqlserver://[serverName[\instanceName][:portNumber]][;property=value[;property=value]]
jdbc:sqlserver://: 固定协议头。localhost:1433: 服务器地址和端口号。localhost表示本地,1433是默认端口,如果使用命名实例,格式可能是localhost\SQLEXPRESS。databaseName=YourDatabaseName: 指定要连接的数据库。encrypt=true;trustServerCertificate=true;: 这是非常重要的配置,尤其是在本地开发时。encrypt=true: 启用 SSL 加密。trustServerCertificate=true: 由于我们通常使用自签名证书进行本地开发,这个参数告诉 JDBC 驱动信任服务器证书,避免 SSL握手失败。在生产环境中,你应该使用正确的、受信任的证书,而不是简单地信任所有证书。
第五步:常见问题与解决方案
-
com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host has failed- 原因: Java 应用无法通过网络连接到 SQL Server。
- 解决方案:
- 检查 SQL Server 服务: 确保你的 SQL Server 服务正在运行。
- 检查防火墙: 检查 Windows 防火墙或其他防火墙是否阻止了
1433端口,可以暂时关闭防火墙测试,或为sqlserver.exe添加防火墙例外。 - 检查 SQL Server 配置: 打开 SQL Server Configuration Manager -> SQL Server 网络配置 -> 你的协议(如
TCP/IP),确保TCP/IP协议已启用,并检查IP 地址中的IPAll,TCP 端口是否为1433。
-
com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'sa'.- 原因: 用户名或密码错误。
- 解决方案:
- 检查用户名和密码: 确认输入的用户名和密码完全正确。
- 检查 SQL Server 身份验证模式:
- 打开 SQL Server Management Studio (SSMS)。
- 右键点击服务器 -> 属性。
- 在 安全性 页面,检查 服务器身份验证 是
Windows 身份验证模式还是SQL Server 和 Windows 身份验证模式。 - 如果是前者,你需要将其改为后者,然后重启 SQL Server 服务。
- 使用 SSMS 尝试用
sa登录,如果忘记密码,可以在 Windows 身份验证模式下重置sa的密码。
-
No suitable driver found for jdbc:sqlserver://...- 原因: JDBC 驱动没有被加载到类路径中。
- 解决方案:
- Maven 项目: 确保
pom.xml中的依赖已正确添加,并且项目已重新构建(在 IDE 中执行Maven -> Reload project)。 - 手动项目: 确认 JDBC 驱动的 JAR 文件已正确添加到项目的库/构建路径中。
- Maven 项目: 确保
-
The driver could not establish a secure connection to SQL Server due to an authentication failure- 原因: 通常是 SSL/TLS 证书验证问题。
- 解决方案:
- 最简单的解决方法是在连接字符串中添加
encrypt=true;trustServerCertificate=true;。注意:这会降低安全性,仅适用于开发和测试环境。 - 在生产环境中,你需要配置正确的、受信任的证书。
- 最简单的解决方法是在连接字符串中添加
第六步:最佳实践
- 使用连接池: 在实际应用中,频繁地创建和关闭数据库连接是非常消耗资源的,应该使用连接池(如 HikariCP, Apache DBCP, C3P0)来管理和复用连接,HikariCP 是目前性能最好的连接池之一。
- 关闭资源: 始终使用
try-with-resources语句来确保Connection,Statement, 和ResultSet等资源在使用后被正确关闭,避免资源泄漏。 - 使用
PreparedStatement: 对于所有包含用户输入的 SQL 查询,都应使用PreparedStatement来防止 SQL 注入攻击。 - 使用日志框架: 使用 SLF4J + Logback 或 Log4j2 等日志框架来记录数据库操作和错误,而不是使用
System.out.println。 - 配置和代码分离: 将数据库 URL、用户名、密码等配置信息放在单独的配置文件(如
application.properties或config.yml)中,而不是硬编码在 Java 代码里。
