連接mysql報“com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException”的錯誤解決

使用jdbc連接mysql數據庫,報錯com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException。

JDBCTest.java代碼爲:

public class JDBCTest {
    public static void main(String[] args) throws Exception {
        Connection connection = null;
        PreparedStatement prepareStatement = null;
        ResultSet rs = null;

        try {
            // 加載驅動
            Class.forName("com.mysql.jdbc.Driver");
            // 獲取連接
            String url = "jdbc:mysql://localhost:3306/demo";
            String user = "root";
            String password = "xxxxxx";
            connection = DriverManager.getConnection(url, user, password);
            // 獲取statement,preparedStatement
            String sql = "select * from tb_user where id=?";
            prepareStatement = connection.prepareStatement(sql);
            // 設置參數
            prepareStatement.setLong(1, 1l);
            // 執行查詢
            rs = prepareStatement.executeQuery();
            // 處理結果集
            while (rs.next()) {
                System.out.println(rs.getString("userName"));
                System.out.println(rs.getString("name"));
                System.out.println(rs.getInt("age"));
                System.out.println(rs.getDate("birthday"));
            }
        } finally {
            // 關閉連接,釋放資源
            if (rs != null) {
                rs.close();
            }
            if (prepareStatement != null) {
                prepareStatement.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
}

百度後有人說原因是連接的mysql數據庫是8.0版本,而項目使用com.mysql.jdbc.Driver驅動包是5.1版本,將項目驅動版本改成8.0.11可以解決。

於是將com.mysql.jdbc.Driver的版本改爲8.0.11,重新執行代碼後報錯:

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Thu May 28 10:34:56 CST 2020 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
看報錯信息的意思是`com.mysql.jdbc.Driver'棄用了,新的驅動是com.mysql.cj.jdbc.Driver。同時下一段的信息意思是不建議在沒有服務器身份驗證的情況下建立SSL連接。根據MySQL 5.5.45+、5.6.26+和5.7.6+的要求,如果沒有設置顯式選項,則必須在默認情況下建立SSL連接。我們需要通過設置useSSL=false顯式地禁用SSL,或者設置useSSL=true併爲服務器證書驗證提供信任存儲。

改下JDBCTest.java:

/**
 * @author Evan
 */
public class JDBCTest {
    public static void main(String[] args) throws Exception {
        Connection connection = null;
        PreparedStatement prepareStatement = null;
        ResultSet rs = null;

        try {
            // 加載驅動,改爲com.mysql.cj.jdbc.Driver
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 獲取連接,設置useSSL=false
            String url = "jdbc:mysql://localhost:3306/ssmdemo?useSSL=false";
            String user = "root";
            String password = "123456";
            connection = DriverManager.getConnection(url, user, password);
            // 獲取statement,preparedStatement
            String sql = "select * from tb_user where id=?";
            prepareStatement = connection.prepareStatement(sql);
            // 設置參數
            prepareStatement.setLong(1, 1l);
            // 執行查詢
            rs = prepareStatement.executeQuery();
            // 處理結果集
            while (rs.next()) {
                System.out.println(rs.getString("userName"));
                System.out.println(rs.getString("name"));
                System.out.println(rs.getInt("age"));
                System.out.println(rs.getDate("birthday"));
            }
        } finally {
            // 關閉連接,釋放資源
            if (rs != null) {
                rs.close();
            }
            if (prepareStatement != null) {
                prepareStatement.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
}

改了之後,繼續執行JDBCTest.java,報錯......

Exception in thread "main" java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
這個錯誤是時區問題,數據庫安裝時默認爲英語,0:00時區,Windows系統中,XP的時區是GMT,而Win7的時區是UTC。mysql返回的時間會比實際時間要早8小時。
上面的提示信息很明顯,我們可以通過配置服務器或者通過serverTimeZone配置Jdbc driver連接參數來指定一個特定的時區。

(1)配置JDBC連接參數。在url連接字符串後面加上?serverTimezone=UTC

改動後的JDBCTest.java:

/**
 * @author Evan
 */
public class JDBCTest {
    public static void main(String[] args) throws Exception {
        Connection connection = null;
        PreparedStatement prepareStatement = null;
        ResultSet rs = null;

        try {
            // 加載驅動,改爲com.mysql.cj.jdbc.Driver
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 獲取連接,設置useSSL=false,serverTimezone=UTC
            String url = "jdbc:mysql://localhost:3306/ssmdemo?useSSL=false&serverTimezone=UTC";
            String user = "root";
            String password = "123456";
            connection = DriverManager.getConnection(url, user, password);
            // 獲取statement,preparedStatement
            String sql = "select * from tb_user where id=?";
            prepareStatement = connection.prepareStatement(sql);
            // 設置參數
            prepareStatement.setLong(1, 1l);
            // 執行查詢
            rs = prepareStatement.executeQuery();
            // 處理結果集
            while (rs.next()) {
                System.out.println(rs.getString("userName"));
                System.out.println(rs.getString("name"));
                System.out.println(rs.getInt("age"));
                System.out.println(rs.getDate("birthday"));
            }
        } finally {
            // 關閉連接,釋放資源
            if (rs != null) {
                rs.close();
            }
            if (prepareStatement != null) {
                prepareStatement.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
}

(2)修改MySQL數據庫配置。

show variables like '%time_zone%';

mysql> show variables like "%time_zone%";
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone |        |
| time_zone        | SYSTEM |
+------------------+--------+

--設置爲東八區(北京時間)
set global time_zone='+8:00';

mysql> set global time_zone='+8:00';
Query OK, 0 rows affected (0.00 sec)

設置完重新打開命令行,進入mysql,查詢time。

mysql> show variables like "%time_zone%";
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone |        |
| time_zone        | +08:00 |
+------------------+--------+
2 rows in set, 1 warning (0.01 sec)

這時候即使jdbc不加serverTimezone=UTC,依然運行正常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章