JDBC 连接 MySQL 时碰到的小坑

最近从MS SQL Server换到了MySQL,已经是8.11版本了,安装的时候似乎还用了新的身份认证方式之类的,连接过程中也是磕磕绊绊,碰到很多奇奇怪怪的问题,在此记录下来。



驱动加载:

以前使用JDBC时,都是导入相应的JDBC驱动jar包,然后使用

Class.forName(driverName);

加载驱动,再进行数据库连接,在使用MySQL 8.11版本及其对应的Connector时,如果使用上述代码加载com.mysql.jdbc.Driver的话,控制台会输出一行信息:

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.

大概意思是加载的这个类已被弃用,新驱动类是com.mysql.cj.jdbc.Driver,通过SPI自动注册,通常不需要手动加载。注释掉Class.forName后运行就不会产生该输出了。

连接数据库时的URL:

URL前半部分格式固定,需要附加的参数是通过类似网址中的QueryString附着在后面的,格式如下:

jdbc:<_database>://<address>:<port>/<database_name>[?_key1=_value1[&_key2=_value2[&_key3=_value3]...]]


在此仅列举用到的几个参数:

不加参数进行连接时首先会输出这样一行提示信息:

Tue May 08 20:16:40 CST 2018 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.

大概意思是不建议在没有服务器身份验证的情况下建立SSL连接等等,由于本人对SSL并不了解,就直接按照提示在加上参数useSSL=false,就不会产生该输出了。



接下来遇到的错误是一个关于时区的SQLException:The server time zone value......

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.

大概意思是服务器的时区值有问题,我这直接就是一团乱码了,按照提示加上参数serverTimezone=Hongkong,就不会产生这个异常了,对于该参数的取值可以查阅相关资料获得,已知东8区可以用Hongkong、Asia/Shanghai或者Asia/Hongkong作为参数取值



SQLNonTransientConnectionException: Public Key Retrieval is not allowed

这时可能程序已经能够正常连接数据库了,不过我在调试成功后第二天再次连接时(未对代码进行改动),抛出了一个异常并连接失败,多次尝试无果,该异常如下:

SQLNonTransientConnectionException: Public Key Retrieval is not allowed

对于这个异常网上相关资料很少,多为英文,误打误撞下竟然解决了这个问题,方法为添加一个参数allowPublicKeyRetrieval=true,即可正常连接,而且在连接成功一次后,删除此参数仍然可以正常连接(不懂得都是玄学)......,该方法来自(https://bugs.mysql.com/bug.php?id=75670)下一位dalao的评论:

[20 Aug 2015 19:57] Daniel So
Added the following entry to the Connector/J 6.0 changelog: 

"If the MySQL server‘s default authentication method was SHA256 but neither one of the Connector/J connection properties allowPublicKeyRetrieval and serverRSAPublicKeyFile was set, the authentication failed with a TransientConnectionException, complaining that the public key could not be retrieved. With this fix, authentication continues in the situation, allowing other enabled authentication methods to be tried."

然而并没有看懂。



另外就是字符编码问题,本人服务器默认使用的编码为UTF-8MB4,Eclipse默认编码均使用UTF-8,所以并未处理编码问题。

若需要进行编码转换需要附加参数useUnicode=true 和 characterEncoding=UTF-8



其他重要参数(转自:https://blog.csdn.net/wpydaguan/article/details/41148047):

参数名称 参数说明 缺省值 最低版本要求
user 数据库用户名(用于连接数据库)   所有版本
password 用户密码(用于连接数据库)   所有版本
useUnicode 是否使用Unicode字符集,如果参数characterEncoding设置为gb2312或gbk,本参数值必须设置为true false 1.1g
characterEncoding 当useUnicode设置为true时,指定字符编码。比如可设置为gb2312或gbk false 1.1g
autoReconnect 当数据库连接异常中断时,是否自动重新连接? false 1.1
autoReconnectForPools 是否使用针对数据库连接池的重连策略 false 3.1.3
failOverReadOnly 自动重连成功后,连接是否设置为只读? true 3.0.12
maxReconnects autoReconnect设置为true时,重试连接的次数 3 1.1
initialTimeout autoReconnect设置为true时,两次重连之间的时间间隔,单位:秒 2 1.1
connectTimeout 和数据库服务器建立socket连接时的超时,单位:毫秒。 0表示永不超时,适用于JDK 1.4及更高版本 0 3.0.1
socketTimeout socket操作(读写)超时,单位:毫秒。 0表示永不超时 0 3.0.1


特别注意!在某些通过配置文件来指定URL的情况下(如xml配置文件),URL后参数的隔离符号&需要使用&amp;转义为&,其他符号也是如此:

HTML中常用的特殊字符(Character Entities)

显示结果 说明 Entity Name Entity Number
  显示一个空格 &nbsp;  
< 小于 &lt; <
> 大于 &gt; >
& &符号 &amp; &
双引号 &quot; "

其他常用的字符实体(Character Entities)

显示结果 说明 Entity Name Entity Number
? 版权 &copy; ©
? 注册商标 &reg; ®
× 乘号 &times; ×
÷ 除号 &divide; ÷


Java Web中遇到的坑:

No suitable driver found for jdbc:mysql://...

前面提到MySQL启用的旧驱动使用了新的通过SPI自动注册的驱动,在普通Java程序下可以正常运行,但是在Java Web项目中运行在Tomcat8.5环境下时,进行数据库连接操作会抛出异常:

java.sql.SQLException: No suitable driver found for jdbc:mysql://...

大概的意思是找不到合适的JDBC驱动程序,经过检查,已经将使用到的驱动jar包放到了Tomcat的lib目录下,Eclipse中的构建路径也包含了该jar包,在执行连接操作前向控制台打印所用驱动类也存在:

			System.out.println(com.mysql.cj.jdbc.Driver.class);

/*
*输出:
**
*class com.mysql.cj.jdbc.Driver
*
*/

经过搜索得到的答案基本一致(转自:http://www.blogjava.net/w2gavin/articles/217864.html):

    今天出现编码出现了No suitable driver found for jdbc,又是找遍了网上的资料,基本上都说是三个问题:
    一是:连接URL格式出现了问题(Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/XX","root","XXXX")
    二是:驱动字符串出错(com.mysql.jdbc.Driver)
    三是Classpath中没有加入合适的mysql_jdbc驱动
    经过我的仔细检查,这三种错误我都没有犯,为什么呢?
    尝试着将mysql-connector-java-3.1.14-bin.jar的jar包加入C:\Program Files\Java\jre1.6.0_02\lib\ext文件夹下,问题解决了!!
    原来是不仅仅要求将驱动加入classpath中,而且需要将该jar包加入到java运行环境的外部jar包中,唉,下次这种低级错误还是少犯为妙。

对于这三个说法,本人针对前两条进行了检查,并没有错误,第三条个人认为不正确,Tomcat会自动加载lib下的jar包,况且上面在打印驱动类的Class对象时也确实能看到该类已经被加载,对于下面将驱动jar包放入系统jre下的方(玄)法(学)也并未尝试,不过,在连接数据库操作前加了主动加载驱动类的代码后竟然神(玄)奇(学)的好了

			System.out.println(com.mysql.cj.jdbc.Driver.class);
			Class.forName(driverName);
			System.out.println("connecting...");
			conn = DriverManager.getConnection(URL, uName, uPwd);
			System.out.println("connect success!");
/*
*输出:
**
*class com.mysql.cj.jdbc.Driver
*connecting...
*connect success!
*
*/

可以看到在手动加载之前该类已经注册,因此这个玄学问题还希望请知道的dalao指教一二!



目前遇到的问题就这些,日后遇到新的问题继续补充,文中理解的若有错误还请dalao们指正,欢迎大家的讨论交流。

原文地址:https://www.cnblogs.com/Mimick/p/9011003.html

时间: 2024-08-27 14:21:20

JDBC 连接 MySQL 时碰到的小坑的相关文章

解决JDBC连接MySQL时发出的警告WARN: Establishing SSL connection without server&#39;s identity verification ...

对于稍微有点强迫症的我来说,每次正常加载MySQL驱动后,eclipse的控制台总是出现一行红色警告: Fri Mar 30 14:55:35 CST 2018 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 m

jdbc连接mysql时发出警告:WARN: Establishing SSL connection without server&#39;s identity verification is not recommended...

警告信息如图: 解决: 在jdbcurl后面加上这个&useSSL=false参数: jdbc连接mysql时发出警告:WARN: Establishing SSL connection without server's identity verification is not recommended... 原文地址:https://www.cnblogs.com/xiamaojjie/p/12216086.html

jdbc连接mysql 时的中文乱码问题解决

在用 jdbc 向 mysql 数据库插入中文时出现了乱码,严格来说是通过 Hibernate.记录下搜索和查文档以后找到的解决办法. 首先要告诉数据库要插入的字符串使用的字符集,mysql 默认使用的字符集是 latin1.我要保存的字符串是 UTF-8 编码的(字符集是 Unicode),所以包含这个字段的表应该使用 UTF-8 编码.这里有几种解决办法. 在建立数据库的时候指定数据库的字符集编码,这样,这个数据库的所有表都会默认使用数据库的字符集编码.如 create database f

分页查询信息(使用jdbc连接mysql数据库实现分页查询任务)

         分页查询信息       使用jdbc连接mysql数据库实现分页查询任务 通过mysql数据库提供的分页机制,实现商品信息的分页查询功能,将查询到的信息显示到jsp页面上. 本项目时一个简单的运用eclipse+jdbc+mysql的小程序. 连接的数据库名称为db_database11,属性如下: 1.创建名为com.pmf.bean的包,包中是名为Product的类,用于封装商品信息. 全部代码如下: package com.pmf.bean; /** * 商品 * */

Java基础102 完整的JDBC连接MySQL数据库和Oracle数据库的方法

本文知识点(目录): 1.jdbc连接MySQL数据库    2.jdbc连接Oracle数据库    3.附录[本文jdbc连接MySQL或Oracle数据库的全部代码(合起来,做对比)] 1.JDBC连接MySQL数据库 1.1.我用到的jar包 1.2.实例演示 MySQL建表语句 1 -- MySQL建表语句 2 create table user( 3 id number(5) primary key auto_increment, 4 account varchar(20) not

java运行代码连接mysql时提示:找不到类错误

使用IntelliJ IDEA Community Edition进行代码编写.. 使用一下代码连接mysql时出现了:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver错误 然后就很好奇,import都能导入数据. 后来用idea工具打开以前的练习,发现架包也存在. 但是新建的练习就没有把架包弄进来.然后出现了这类错误.. 原因是:使用idea工具开发时,如果之前练习有添加相应的数据,那么在external libraries中是能显

java jdbc 连接mysql数据库 实现增删改查

好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打交道非常基础的一个知识,也是比较接近底层的,在实际的工作中大家用得更多的其实还是比较成熟的框架,例如Hibernate.Mybatis. 但是作为这些成熟框架的底层的jdbc却也是我们应该去掌握的,只有了解了jdbc的增删改查,这样在以后如果有兴趣去研究Hibernate或者Mybatis的源代码的

JDBC连接MySQL数据库及演示样例

JDBC是Sun公司制定的一个能够用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,能够为多种关系数据库提供统一訪问,它由一组用Java语言编写的类和接口组成.JDBC为数据库开发者提供了一个标准的API,据此能够构建更高级的工具和接口,使数据库开发者能够用纯 Java API 编写数据库应用程序,而且可跨平台执行,而且不受数据库供应商的限制.

使用JDBC连接MySQL数据库--典型案例分析(八)----实现员工数据的分页查询

转载请注明:http://blog.csdn.net/uniquewonderq 问题: 使用JDBC连接Mysql数据库,实现对Emp表数据的分页查询功能. 方案: 对于较大的数据量,通常采用分页查询的方式.不同的数据库产品有不同的数据库级的分页查询策略.例如:Oracle通常使用rownum的方式:而Mysql使用limit的方式. Oracle采用rownum和子查询实现分页查询,SQL语句如下, select * from (select rownum rn,empno,ename,jo