目录
- 准备工作
- 安装 SQL Server 数据库
- 获取数据库连接信息
- 准备 Java 开发环境
- 下载 SQL Server JDBC 驱动
- 添加 JDBC 驱动到项目
- Maven 项目
- Gradle 项目
- 普通 JAR 项目
- Java 连接代码示例
- 基础连接代码
- 使用
try-with-resources的最佳实践 - 执行查询和更新操作
- 最佳实践
- 使用连接池
- 使用
PreparedStatement防止 SQL 注入 - 处理异常
- 常见问题与解决方案
ClassNotFoundExceptionConnection refused或Network errorLogin failed for user- 驱动版本与 SQL Server 版本不匹配
准备工作
在开始编码之前,请确保您已经准备好以下环境:

a. 安装 SQL Server 数据库
确保您有一台可以正常访问的 SQL Server 实例(可以是本地安装的,也可以是远程服务器)。
b. 获取数据库连接信息
您需要以下关键信息来建立连接:
- 服务器名称:
localhost(本地),168.1.100(IP地址), 或SERVER_NAME(实例名)。 - 端口号: 默认为
1433,如果不是默认端口,需要提供。 - 数据库名称: 您要连接的数据库,
mydatabase。 - 用户名: 具有访问权限的数据库用户,
sa。 - 密码: 对应用户的密码。
c. 准备 Java 开发环境
确保您的系统已安装:
- JDK (Java Development Kit) 8 或更高版本。
- IDE (集成开发环境),如 IntelliJ IDEA、Eclipse 或 VS Code。
d. 下载 SQL Server JDBC 驱动
Java 通过 JDBC (Java Database Connectivity) 协议连接数据库,而 SQL Server 提供了自己的 JDBC 驱动程序。

- 下载地址: Microsoft JDBC Driver for SQL Server
- 选择版本: 根据您的 SQL Server 版本和 JDK 版本选择合适的驱动,新版本的驱动兼容旧版本的 SQL Server,下载
.jar文件即可。
添加 JDBC 驱动到项目
您需要将下载的 JDBC 驱动 JAR 文件添加到您的 Java 项目的类路径中。
a. Maven 项目 (推荐)
这是最简单和最推荐的方式,在您的 pom.xml 文件中添加以下依赖。
<!-- 请根据您下载的驱动版本进行修改 -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>11.2.1.jre8</version> <!-- 11.2.1.jre8 -->
</dependency>
Maven 会自动下载并管理依赖。
b. Gradle 项目
在您的 build.gradle 或 build.gradle.kts 文件中添加依赖。
// build.gradle // 请根据您下载的驱动版本进行修改 implementation 'com.microsoft.sqlserver:mssql-jdbc:11.2.1.jre8' // 11.2.1.jre8
c. 普通 JAR 项目
如果您不使用构建工具,可以手动添加:
- 将下载的
mssql-jdbc-xxx.jre8.jar(文件名可能不同) 复制到您的项目目录下,lib文件夹。 - 在您的 IDE 中,右键点击项目 -> Build Path / Project Structure -> Libraries / Dependencies。
- 添加外部 JAR,并选择您刚刚复制的文件。
- 如果使用命令行编译,需要使用
-cp参数指定 JAR 路径:javac -cp ".;path/to/your/mssql-jdbc-11.2.1.jre8.jar" YourProgram.java java -cp ".;path/to/your/mssql-jdbc-11.2.1.jre8.jar" YourProgram
注意:在 Linux 或 macOS 上,路径分隔符是 而不是 。
Java 连接代码示例
这里提供从简单到完整的代码示例。
a. 基础连接代码
这是一个最简单的示例,用于建立连接。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class SimpleConnection {
public static void main(String[] args) {
// 1. 定义数据库连接信息
String connectionUrl =
"jdbc:sqlserver://localhost:1433;" + // 服务器地址和端口
"databaseName=mydatabase;" + // 数据库名
"user=sa;" + // 用户名
"password=YourStrong!Password123;"; // 密码
// try-with-resources 语句会自动关闭连接
try (Connection conn = DriverManager.getConnection(connectionUrl)) {
if (conn != null) {
System.out.println("连接成功!");
}
} catch (SQLException e) {
System.err.println("连接失败!");
e.printStackTrace();
}
}
}
b. 使用 try-with-resources 的最佳实践
上面的例子已经使用了 try-with-resources,这是 Java 7 引入的最佳实践,它可以确保 Connection、Statement 和 ResultSet 等资源在使用完毕后被自动关闭,避免资源泄漏。
c. 执行查询和更新操作
一个完整的示例,包括查询和更新数据。
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 JdbcExample {
// 数据库连接信息
private static final String DB_URL = "jdbc:sqlserver://localhost:1433;databaseName=mydatabase;user=sa;password=YourStrong!Password123;";
public static void main(String[] args) {
// 创建表并插入一条数据 (DDL/DML)
createAndInsertData();
// 查询数据
queryData();
}
// 创建表并插入数据
public static void createAndInsertData() {
String createTableSql = "IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='Employees' and xtype='U') CREATE TABLE Employees (id INT PRIMARY KEY, name NVARCHAR(50), age INT)";
String insertSql = "INSERT INTO Employees (id, name, age) VALUES (?, ?, ?)";
// 使用 try-with-resources 确保 Statement 和 Connection 被关闭
try (Connection conn = DriverManager.getConnection(DB_URL);
Statement stmt = conn.createStatement()) {
// 创建表
stmt.execute(createTableSql);
System.out.println("表 'Employees' 已存在或已创建。");
// 插入数据 (使用 PreparedStatement 防止 SQL 注入)
try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
pstmt.setInt(1, 1);
pstmt.setString(2, "张三");
pstmt.setInt(3, 30);
int rowsAffected = pstmt.executeUpdate();
System.out.println(rowsAffected + " 行数据已插入。");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
// 查询数据
public static void queryData() {
String selectSql = "SELECT id, name, age FROM Employees";
try (Connection conn = DriverManager.getConnection(DB_URL);
PreparedStatement pstmt = conn.prepareStatement(selectSql);
ResultSet rs = pstmt.executeQuery()) {
System.out.println("\n--- 查询结果 ---");
while (rs.next()) {
// 通过列名获取数据,更健壮
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
System.out.println("ID: " + id + ", 姓名: " + name + ", 年龄: " + age);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
最佳实践
a. 使用连接池
每次创建和销毁连接都非常消耗资源,在高并发应用中,必须使用连接池来管理数据库连接。
-
常用连接池: HikariCP (性能优秀), Apache DBCP, C3P0。
-
Maven 依赖 (HikariCP):
<dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>5.0.1</version> </dependency> -
使用 HikariCP 示例:
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; public class HikariCPExample { public static void main(String[] args) { HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:sqlserver://localhost:1433;databaseName=mydatabase"); config.setUsername("sa"); config.setPassword("YourStrong!Password123"); config.addDataSourceProperty("cachePrepStmts", "true"); config.addDataSourceProperty("prepStmtCacheSize", "250"); config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); try (HikariDataSource ds = new HikariDataSource(config); Connection conn = ds.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT 'Hello HikariCP'")) { if (rs.next()) { System.out.println(rs.getString(1)); } } catch (Exception e) { e.printStackTrace(); } } }
b. 使用 PreparedStatement
- 防止 SQL 注入:
PreparedStatement会对输入参数进行转义,是防止 SQL 注入攻击的标准做法。 - 提高性能: 对于重复执行的 SQL,数据库可以预编译
PreparedStatement,提高执行效率。
c. 处理异常
总是妥善处理 SQLException,不要简单地 e.printStackTrace(),在实际应用中,应该记录日志(如使用 SLF4J + Logback)并向用户返回友好的错误信息。
常见问题与解决方案
a. ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver
原因: JVM 的类路径中没有包含 SQL Server JDBC 驱动。 解决方案:
- 确认您已经下载了 JDBC 驱动 JAR 文件。
- 确认您已将该 JAR 文件正确添加到项目的类路径中(参考第 2 节)。
- 如果使用 IDE,尝试 "Clean" 和 "Rebuild" 项目。
b. Connection refused: connect 或 The TCP/IP connection to the host has failed
原因: 无法连接到指定的 SQL Server 服务器。 解决方案:
- 检查服务器地址和端口: 确认
localhost和1433(或您配置的端口) 是否正确。 - 检查 SQL Server 服务: 确保您的 SQL Server 服务正在运行,可以在 Windows 的 "服务" 中查找 "SQL Server (...)" 并启动它。
- 检查防火墙: 检查 Windows 防火墙或任何网络防火墙是否阻止了
1433端口的入站连接,可以临时关闭防火墙进行测试。 - 检查 SQL Server 的 TCP/IP 协议:
- 打开 SQL Server Configuration Manager。
- 展开 "SQL Server 网络配置"。
- 点击 "SQLEXPRESS 的协议" (或您的实例名)。
- 确保
TCP/IP协议是 已启用 的。 - 右键点击
TCP/IP,选择 "属性",在 "IP 地址" 选项卡中,确保IPAll下的TCP 动态端口是空的,TCP 端口是1433(或其他您想要的端口),然后点击"确定"。 - 重启 SQL Server 服务 使配置生效。
c. Login failed for user 'sa'.
原因: 用户名或密码错误,或者该用户没有登录权限。 解决方案:
- 核对用户名和密码: 确保输入的
sa和密码完全正确。 - 检查 SQL Server 身份验证模式:
- 在 SQL Server Management Studio (SSMS) 中,右键点击服务器实例 -> "属性" -> "安全性"。
- 确保 "服务器身份验证" 设置为 "SQL Server 和 Windows 身份验证模式",如果只是 "Windows 身份验证模式",则无法使用
sa用户名登录。
- 重置
sa密码:- 以 Windows 身份验证登录到 SSMS。
- 在 "查询" 窗口中执行以下命令:
ALTER LOGIN sa WITH PASSWORD = 'YourNewStrongPassword123'; GO
- 然后在 Java 代码中使用新密码。
d. 驱动版本与 SQL Server 版本不匹配
原因: 使用了非常旧的 JDBC 驱动去连接新版本的 SQL Server,或者反之。 解决方案:
- 查看您下载的 JDBC 驱动的官方文档,确认其支持的 SQL Server 版本。
- 使用最新版本的 JDBC 驱动是最安全的选择,因为它通常向后兼容旧版本的 SQL Server。
希望这份详细的指南能帮助您成功地在 Java 中连接 SQL Server!
