我们将使用 JDBC (Java Database Connectivity),这是 Java 连接数据库的标准方式。
第一步:准备工作
在编写代码之前,你需要准备好两样东西:
SQL Server 数据库环境
确保你已经有一个可用的 SQL Server 实例,并且知道以下连接信息:
- 服务器地址: 通常是
localhost(如果你和数据库在同一台机器上)或一个 IP 地址/主机名。 - 端口号: 默认是
1433。 - 数据库名: 你要连接的具体数据库的名称。
- 用户名: 具有访问该数据库权限的用户名。
- 密码: 对应用户名的密码。
JDBC 驱动程序
JDBC 驱动是 Java 和 SQL Server 之间的桥梁,你需要下载 Microsoft 官方提供的 JDBC 驱动。
如何选择版本?
- 选择与你的 Java 版本 和 SQL Server 版本 兼容的驱动。
- 对于大多数新项目,推荐使用最新的稳定版本。
如何使用下载的驱动?
下载后,你会得到一个 .jar 文件(mssql-jdbc-12.4.1.jre11.jar),你需要将这个 JAR 文件添加到你的 Java 项目的类路径(Classpath)中。
添加方式(根据你的开发环境):
-
IDE (如 IntelliJ IDEA 或 Eclipse):
- 右键你的项目 ->
Project Structure(或Properties)。 - 找到
Libraries或Java Build Path->Libraries。 - 点击
Add External JARs...或Add JARs...,然后选择你下载的.jar文件。
- 右键你的项目 ->
-
Maven 项目 (推荐): 这是最简单、最推荐的方式,你不需要手动下载任何文件,只需在
pom.xml文件中添加依赖即可,Maven 会自动帮你下载和管理。<dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <!-- 请根据你的 Java 版本选择合适的驱动版本。 如果你使用 Java 11, 17, 21, 请使用 .jre11 结尾的版本。 如果你使用 Java 8, 请使用 .jre8 结尾的版本。 --> <version>12.4.1.jre11</version> </dependency> -
Gradle 项目: 在
build.gradle文件中添加依赖:implementation group: 'com.microsoft.sqlserver', name: 'mssql-jdbc', version: '12.4.1.jre11'
第二步:编写 Java 连接代码
这里我们提供一个完整的示例,包括连接、执行查询、处理结果和关闭资源。
示例:查询 Student 表
假设你的 SQL Server 数据库中有一个 Student 表,结构如下:
CREATE TABLE Student (
id INT PRIMARY KEY,
name NVARCHAR(50),
age INT,
enrollment_date DATE
);
INSERT INTO Student VALUES (1, '张三', 20, '2025-09-01');
INSERT INTO Student VALUES (2, '李四', 21, '2025-09-01');
INSERT INTO Student VALUES (3, '王五', 22, '2025-09-01');
Java 代码 (JDBCExample.java)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCExample {
// --- 请根据你的实际情况修改以下信息 ---
private static final String DB_URL = "jdbc:sqlserver://localhost:1433;databaseName=YourDatabaseName;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);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, name, age FROM Student")) {
// 检查连接是否成功
if (conn != null) {
System.out.println("连接到 SQL Server 成功!");
}
System.out.println("----- 学生列表 -----");
// 遍历结果集
while (rs.next()) {
// 通过列名获取数据,更推荐,不易出错
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
// 也可以通过列索引获取 (1代表第一列, 2代表第二列...)
// int id = rs.getInt(1);
System.out.println("ID: " + id + ", 姓名: " + name + ", 年龄: " + age);
}
} catch (SQLException e) {
// 处理 JDBC 错误
System.err.println("数据库连接或查询出错!");
e.printStackTrace();
}
// try-with-resources 会自动关闭 Connection, Statement, 和 ResultSet
}
}
第三步:代码详解
-
加载驱动 (隐式): 从 JDBC 4.0 (Java 6) 开始,不再需要显式地使用
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver")来加载驱动,只要驱动 JAR 在类路径中,DriverManager在尝试连接时会自动找到并加载它。 -
连接字符串:
jdbc:sqlserver://<server>:<port>;databaseName=<database>;encrypt=<value>;trustServerCertificate=<value>;jdbc:sqlserver://: 固定协议头。localhost:1433: 服务器地址和端口。databaseName=YourDatabaseName: 指定要连接的数据库。encrypt=false;trustServerCertificate=true;: 这两个参数在本地开发和测试时非常重要!encrypt: 是否加密连接,对于生产环境,建议设置为true。trustServerCertificate=true:encrypt=true,但你的 SQL Server 使用的是自签名证书(例如本地开发时),你需要设置此参数为true来信任该证书,否则会抛出 SSL 异常。注意:在生产环境中,你应该使用由受信任的证书颁发机构签名的证书,而不是简单地信任所有证书。
-
获取连接:
DriverManager.getConnection(DB_URL, USER, PASS)方法尝试使用提供的 URL、用户名和密码建立到数据库的连接。 -
创建
Statement:Connection.createStatement()用于创建一个Statement对象,用于向数据库发送 SQL 语句。 -
执行查询:
stmt.executeQuery("SELECT ...")用于执行一个返回结果集的查询(如SELECT),它返回一个ResultSet对象。 -
处理结果集 (
ResultSet):rs.next(): 将光标移动到下一行,如果存在下一行,则返回true,否则返回false,通常用在while循环中遍历所有行。rs.getXXX("columnName"): 根据列名获取当前行指定列的值,XXX是数据类型(如getString,getInt,getDate等)。推荐使用列名,因为即使 SQL 查询的列顺序改变,代码也不需要修改。rs.getXXX(int columnIndex): 根据列的索引(从 1 开始)获取值。
-
关闭资源 (
try-with-resources):try (Connection conn = ...; Statement stmt = ...; ResultSet rs = ...)是 Java 7 引入的一个语法糖,它会自动在try块执行完毕后(无论是否发生异常)调用close()方法来关闭资源,这是处理 JDBC 资源的最佳实践,可以防止资源泄漏。
第四步:常见问题与解决方案
连接超时或拒绝连接
- 错误信息:
The TCP/IP connection to the host has failed,Connection refused - 原因:
- SQL Server 服务未启动。
- 防火墙阻止了
1433端口。 - 服务器地址或端口号错误。
- 解决方案:
- 检查 SQL Server 服务是否正在运行。
- 检查 Windows 防火墙或其他安全软件,确保允许 SQL Server 的 TCP/IP 连接。
- 确认连接字符串中的
localhost和1433是否正确,你也可以尝试使用0.0.1代替localhost。
登录失败
- 错误信息:
Login failed for user '...'. - 原因:
- 用户名或密码错误。
- 该用户没有权限访问指定的数据库。
- 解决方案:
- 仔细检查用户名和密码。
- 在 SQL Server Management Studio (SSMS) 中,尝试用相同的凭据登录,确认账户是否有效。
SSL/TLS 加密问题
- 错误信息:
The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. - 原因: 连接字符串中设置了
encrypt=true,但客户端不信任 SQL Server 的证书。 - 解决方案:
- 临时方案 (仅限开发/测试): 在连接字符串中添加
trustServerCertificate=true;。 - 正确方案 (生产环境): 将 SQL Server 的证书(或由 CA 签名的证书)导入到 Java 的信任存储区(Truststore)中,这更复杂,但更安全。
- 临时方案 (仅限开发/测试): 在连接字符串中添加
找不到驱动类或 ClassNotFoundException
- 错误信息:
java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver - 原因: JDBC 驱动的 JAR 文件没有被正确添加到项目的类路径中。
- 解决方案:
- 确认你已下载了正确的 JDBC 驱动 JAR 文件。
- 确认该 JAR 文件已添加到你的 IDE 或构建工具(Maven/Gradle)的类路径中,如果你使用 Maven/Gradle,请确保
pom.xml或build.gradle文件中的依赖配置正确,并刷新了项目。
连接字符串中的参数问题
- 错误信息:
The connection to the host localhost, named instance SQLEXPRESS failed... - 原因: 如果你安装的是 SQL Server Express,它默认使用 "命名实例"(如
SQLEXPRESS),而不是默认的1433端口。 - 解决方案:
- 在连接字符串中,将
localhost:1433改为localhost\\SQLEXPRESS。 -
jdbc:sqlserver://localhost\\SQLEXPRESS;databaseName=YourDatabaseName;...
- 在连接字符串中,将
总结与最佳实践
- 使用连接池: 在实际应用中,频繁地创建和销毁连接是非常消耗资源的,应该使用连接池(如 HikariCP, Apache DBCP)来管理数据库连接,HikariCP 是目前性能最好的连接池之一。
- 使用
PreparedStatement: 对于有参数的查询(SELECT * FROM Student WHERE name = ?),始终使用PreparedStatement,而不是用字符串拼接 SQL,它可以防止 SQL 注入攻击,并且通常性能更好。 - 配置
try-with-resources: 永远使用try-with-resources来管理Connection,Statement, 和ResultSet,确保资源被正确关闭。 - 使用构建工具: 强烈推荐使用 Maven 或 Gradle 来管理项目依赖,这样可以避免手动处理 JAR 文件的版本冲突和更新问题。
