杰瑞科技汇

Java如何连接SQLServer数据库?

我们将使用 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):

    1. 右键你的项目 -> Project Structure (或 Properties)。
    2. 找到 LibrariesJava Build Path -> Libraries
    3. 点击 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
    }
}

第三步:代码详解

  1. 加载驱动 (隐式): 从 JDBC 4.0 (Java 6) 开始,不再需要显式地使用 Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver") 来加载驱动,只要驱动 JAR 在类路径中,DriverManager 在尝试连接时会自动找到并加载它。

  2. 连接字符串: 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 异常。注意:在生产环境中,你应该使用由受信任的证书颁发机构签名的证书,而不是简单地信任所有证书。
  3. 获取连接: DriverManager.getConnection(DB_URL, USER, PASS) 方法尝试使用提供的 URL、用户名和密码建立到数据库的连接。

  4. 创建 Statement: Connection.createStatement() 用于创建一个 Statement 对象,用于向数据库发送 SQL 语句。

  5. 执行查询: stmt.executeQuery("SELECT ...") 用于执行一个返回结果集的查询(如 SELECT),它返回一个 ResultSet 对象。

  6. 处理结果集 (ResultSet):

    • rs.next(): 将光标移动到下一行,如果存在下一行,则返回 true,否则返回 false,通常用在 while 循环中遍历所有行。
    • rs.getXXX("columnName"): 根据列名获取当前行指定列的值,XXX 是数据类型(如 getString, getInt, getDate等)。推荐使用列名,因为即使 SQL 查询的列顺序改变,代码也不需要修改。
    • rs.getXXX(int columnIndex): 根据列的索引(从 1 开始)获取值。
  7. 关闭资源 (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 端口。
    • 服务器地址或端口号错误。
  • 解决方案:
    1. 检查 SQL Server 服务是否正在运行。
    2. 检查 Windows 防火墙或其他安全软件,确保允许 SQL Server 的 TCP/IP 连接。
    3. 确认连接字符串中的 localhost1433 是否正确,你也可以尝试使用 0.0.1 代替 localhost

登录失败

  • 错误信息: Login failed for user '...'.
  • 原因:
    • 用户名或密码错误。
    • 该用户没有权限访问指定的数据库。
  • 解决方案:
    1. 仔细检查用户名和密码。
    2. 在 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 文件没有被正确添加到项目的类路径中。
  • 解决方案:
    1. 确认你已下载了正确的 JDBC 驱动 JAR 文件。
    2. 确认该 JAR 文件已添加到你的 IDE 或构建工具(Maven/Gradle)的类路径中,如果你使用 Maven/Gradle,请确保 pom.xmlbuild.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;...

总结与最佳实践

  1. 使用连接池: 在实际应用中,频繁地创建和销毁连接是非常消耗资源的,应该使用连接池(如 HikariCP, Apache DBCP)来管理数据库连接,HikariCP 是目前性能最好的连接池之一。
  2. 使用 PreparedStatement: 对于有参数的查询(SELECT * FROM Student WHERE name = ?),始终使用 PreparedStatement,而不是用字符串拼接 SQL,它可以防止 SQL 注入攻击,并且通常性能更好。
  3. 配置 try-with-resources: 永远使用 try-with-resources 来管理 Connection, Statement, 和 ResultSet,确保资源被正确关闭。
  4. 使用构建工具: 强烈推荐使用 Maven 或 Gradle 来管理项目依赖,这样可以避免手动处理 JAR 文件的版本冲突和更新问题。
分享:
扫描分享到社交APP
上一篇
下一篇