JDBC - Mysql 8.0.13 連線測試
因為換新的電腦裝置,為其安裝一些開發需要的應用及環境,下載了新版的Mysql8.0.13,在Eclipse中測試連線時遇到一些新的問題,遂記錄。
1. Mysql 5.* 版本JDBC連線
a. 常規匯入 5.* jar 包
b. 編寫測試程式
package wqz.mysql.test; import java.sql.DriverManager; public class Test { private static String url = "jdbc:mysql://localhost:3306/你的庫名";//資料庫服務地址 private static String driver = "com.mysql.jdbc.Driver";//驅動路徑 private static String username = "root"; private static String passworld = "你的密碼"; public static void main(String[] args) throws Exception { Class.forName(driver).newInstance(); //如果能連線成功,則列印連線 System.out.println(DriverManager.getConnection(url, username, passworld)); } }
c. 執行程式
如果資料庫是Mysql 5.* 版本 ,在沒有出現輸入錯誤的連線資訊情況下,會成功輸出資料庫連線物件。
2. 測試 Mysql 8.* 的連線
使用和上述驅動和程式 連線 Mysql 8.*,沒有輸出連線物件,異常資訊如下 :
Tue Oct 30 10:20:06 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to SQL/">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. Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) at com.mysql.jdbc.Util.getInstance(Util.java:387) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:917) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:885) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860) at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2330) at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2083) at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:806) at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:410) at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:328) at java.sql.DriverManager.getConnection(DriverManager.java:664) at java.sql.DriverManager.getConnection(DriverManager.java:247) at wqz.mysql.test.Test.main(Test.java:14) Caused by: java.lang.NullPointerException at com.mysql.jdbc.ConnectionImpl.getServerCharset(ConnectionImpl.java:2997) at com.mysql.jdbc.MysqlIO.sendConnectionAttributes(MysqlIO.java:1936) at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1865) at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1228) at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2253) at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2284) ... 13 more
1. 首先看第一個資訊: ...WARN: Establishing SSL connection without ...
在較高版本的 Mysql 中,引入了 SSL 安全認證,需要擁有一定的安全證書去連線資料庫,而我們沒有證書,所以出現此警告。
解決方式:在原資料庫 url 後加上禁用 SSL 的資訊
//private static String url = "jdbc:mysql://localhost:3306/你的庫名";//資料庫服務地址 private static String url = "jdbc:mysql://localhost:3306/你的庫名?useSSL=false";//資料庫服務地址
執行程式:
Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) at com.mysql.jdbc.Util.getInstance(Util.java:387) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:917) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:885) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860) at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2330) at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2083) at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:806) at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.jdbc.Util.handleNewInstance(Util.java:404) at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:410) at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:328) at java.sql.DriverManager.getConnection(DriverManager.java:664) at java.sql.DriverManager.getConnection(DriverManager.java:247) at wqz.mysql.test.Test.main(Test.java:14) Caused by: java.lang.NullPointerException at com.mysql.jdbc.ConnectionImpl.getServerCharset(ConnectionImpl.java:2997) at com.mysql.jdbc.MysqlIO.sendConnectionAttributes(MysqlIO.java:1936) at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1865) at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1228) at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2253) at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2284) ... 13 more
可見,上述警告已經不再出現,但仍無法連線成功。
2. 解決驅動問題
在安裝Mysql過程中會提示安裝Connector/j,其中包含適應Mysql版本的JDBC連線驅動
將其匯入到專案中(如果沒有此驅動,可去mysql官網下載),並刪除之前的驅動:
對比之前的驅動,由5.* 變成了 8.*,此時的程式沒有變化:
package wqz.mysql.test; import java.sql.DriverManager; public class Test { private static String url = "jdbc:mysql://localhost:3306/你的庫?useSSL=false"; private static String driver = "com.mysql.jdbc.Driver"; private static String username = "root"; private static String passworld = "你的密碼"; public static void main(String[] args) throws Exception { Class.forName(driver).newInstance(); //如果能連線成功,則列印連線 System.out.println(DriverManager.getConnection(url, username, passworld)); } }
執行程式:
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. 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. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:76) at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:835) at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:455) at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240) at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:207) at java.sql.DriverManager.getConnection(DriverManager.java:664) at java.sql.DriverManager.getConnection(DriverManager.java:247) at wqz.mysql.test.Test.main(Test.java:14) Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: 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. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:85) at com.mysql.cj.util.TimeUtil.getCanonicalTimezone(TimeUtil.java:132) at com.mysql.cj.protocol.a.NativeProtocol.configureTimezone(NativeProtocol.java:2234) at com.mysql.cj.protocol.a.NativeProtocol.initServerSession(NativeProtocol.java:2258) at com.mysql.cj.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:1319) at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:966) at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:825) ... 6 more
程式仍然執行失敗,根據異常資訊(主要是上面紅色加大部分資訊)
解決問題:
1. 解決驅動類路徑問題
之前版本的驅動類的 全限定名為 com.mysql.jdbc.Driver, 較新版本的驅動類的包結構發生了改變,全限定名變為 com.mysql .cj. jdbc.Driver , 更改即可
//com.mysql.jdbc.Driver com.mysql.cj.jdbc.Driver
2. 解決時區問題 ...The server time zone value '???ú±ê×??±??'...
解決此問題只需要在原 url 後附加 serverTimezone=UTC
//private static String url = "jdbc:mysql://localhost:3306/你的庫?useSSL=false"; private static String url = "jdbc:mysql://localhost:3306/你的庫?useSSL=false&serverTimezone=UTC";
此時的程式變為:
package wqz.mysql.test; import java.sql.DriverManager; public class Test { private static String url = "jdbc:mysql://localhost:3306/你的庫?useSSL=false&serverTimezone=UTC"; private static String driver = "com.mysql.cj.jdbc.Driver"; private static String username = "root"; private static String passworld = "你的密碼"; public static void main(String[] args) throws Exception { Class.forName(driver).newInstance(); //如果能連線成功,則列印連線 System.out.println(DriverManager.getConnection(url, username, passworld)); } }
執行程式:成功輸出連線物件
over