首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java Web 連接 MySQL:修改連線類用戶名密碼無效之謎 — 連線池快取與配置檔優先級

     編輯:程式設計綜合問答

現象描述

  • Java Web 專案,自寫 `ConnDB` 工具類連接 MySQL
  • 程式碼中硬編碼 `dbUrl` 含 `user=root&password=`
  • **第一次連線成功**
  • **修改類中用戶名/密碼後,重新部署/重啟,仍能連線** (甚至改錯也能連)
  • 疑問:類中的帳密還有用嗎?真正生效在哪?

根因:連線池 / DataSource 配置優先級 > 程式碼硬編碼

**真正生效的帳密在以下位置 (優先級由高到低)**:

  1. JNDI DataSource (應用伺服器配置):`context.xml` / `server.xml` / 管理主控台定義的 ``
  2. Spring Boot / Spring `application.yml`:`spring.datasource.username/password`
  3. 獨立連線池配置檔:HikariCP `HikariConfig`、Druid `druid.properties`、C3P0 `c3p0-config.xml`
  4. 程式碼 `DriverManager.getConnection(url, user, pass)` 參數 (你的 `ConnDB` 類)

為什麼「改錯也能連」?

  • 專案**實際使用了連線池 / JNDI DataSource** (如 Tomcat `context.xml` 定義)
  • 啟動時連線池**預先建立連線** 並存入池中
  • 你的 `ConnDB.getConnection()` 可能**根本沒被呼叫**,或呼叫時從池取出已建立連線
  • 即使程式碼 URL 寫錯,**池裡的連線早就用正確帳密建好**了

驗證步驟

  1. 檢查 `web.xml` / `context.xml` / `server.xml` 是否有 `>> 正在建立新連線: " + dbUrl);` 觀察是否真執行
  2. 重啟資料庫服務 → 專案若不重啟仍能查詢 → **確定用連線池**

ConnDB 類重構建議 (現代化)


public class ConnDB {
    // 1. 移除硬編碼,從配置讀取
    private static final String URL = Config.get("db.url");
    private static final String USER = Config.get("db.user");
    private static final String PASS = Config.get("db.pass");
    private static final String DRIVER = Config.get("db.driver", "com.mysql.cj.jdbc.Driver");

    // 2. 使用 HikariCP 連線池 (單例)
    private static final HikariDataSource ds = new HikariDataSource();
    static {
        ds.setJdbcUrl(URL);
        ds.setUsername(USER);
        ds.setPassword(PASS);
        ds.setDriverClassName(DRIVER);
        ds.setMaximumPoolSize(20);
        ds.setMinimumIdle(5);
        ds.setConnectionTimeout(30000);
        ds.setIdleTimeout(600000);
        ds.setMaxLifetime(1800000);
        ds.setPoolName("MyAppPool");
    }

    // 3. 獲取連線 (從池取出)
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    // 4. 關閉資源 (歸還池)
    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        try { if (rs != null) rs.close(); } catch (SQLException ignore) {}
        try { if (stmt != null) stmt.close(); } catch (SQLException ignore) {}
        try { if (conn != null) conn.close(); } catch (SQLException ignore) {}
    }

    // 5. 應用關閉時關閉池
    public static void shutdown() {
        if (!ds.isClosed()) ds.close();
    }
}

配置檔範例 (application.properties / db.properties)


db.url=jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
db.user=my_real_user
db.pass=my_real_password
db.driver=com.mysql.cj.jdbc.Driver

總結

**類中帳密無效,因為專案實際用連線池/JNDI DataSource**,真正帳密在**伺服器配置 / Spring 配置 / 連線池配置檔**。解決方法:
1. 找到真實配置位置修改帳密
2. 重構 `ConnDB` 整合 HikariCP、讀取外部配置
3. 理解 **配置檔 > 程式碼** 的優先級鏈路

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved