最近从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们指正,欢迎大家的讨论交流。

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

  1. python无法连接mysql,有个小坑,需要注意一下!

    尝试用python链接mysql数据库,按照教程里链接了小半夜,就是没有链接上,找了各种文章,最后发现是版本的问题,我想使用的模块是MySQLdb,刚刚去他们的官网看了一下,最近一次更新是2014年, ...

  2. 使用JDBC连接MySql时出现: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

    在连接字符串后面加上?serverTimezone=UTC 其中UTC是统一标准世界时间. 完整的连接字符串示例:jdbc:mysql://localhost:3306/test?serverTime ...

  3. JDBC连接mysql时出现的ssl问题

    使用MySQL数据库时出现如下错误: WARN: Establishing SSL connection without server's identity verification is not r ...

  4. JDBC连接MySql,配置url报错

    使用JDBC连接MySql时出现:The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one ...

  5. 被缠上了,小王问我怎么在 Spring Boot 中使用 JDBC 连接 MySQL

    上次帮小王入了 Spring Boot 的门后,他觉得我这个人和蔼可亲.平易近人,于是隔天小王又微信我说:"二哥,快教教我,怎么在 Spring Boot 项目中使用 JDBC 连接 MyS ...

  6. 对于使用JDBC连接mysql数据时The server time zone value '¤¤°ê¼Ð·Ç®É¶¡'...的异常问题解决。

    相信很多小伙伴和我一样遇到了这类问题,在使用JDBC连接mysql数据库的时候发生SQLException如下所示的异常情况! java.sql.SQLException: The server ti ...

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

             分页查询信息       使用jdbc连接mysql数据库实现分页查询任务 通过mysql数据库提供的分页机制,实现商品信息的分页查询功能,将查询到的信息显示到jsp页面上. 本项目 ...

  8. JDBC——使用JDBC连接MySQL数据库

    在JDBC--什么是JDBC一文中我们已经介绍了JDBC的基本原理. 这篇文章我们聊聊如何使用JDBC连接MySQL数据库. 一.基本操作 首先我们需要一个数据库和一张表: CREATE DATABA ...

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

    好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...

随机推荐

  1. ZOJ 3593 One Person Game(拓展欧几里得求最小步数)

    One Person Game Time Limit: 2 Seconds      Memory Limit: 65536 KB There is an interesting and simple ...

  2. POJ 1222 EXTENDED LIGHTS OUT(反转)

    EXTENDED LIGHTS OUT Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12616   Accepted: 8 ...

  3. UI“三重天”之实践Uiautomator1

    说起来Uiautomator也有一年没碰过了.借此来回顾.总结一下. 也是阅读<精通APP自动化测试>一书.实践出真知的一个框架.编写了部分移动端UI自动化脚本.后续再深入学习. 虽然现在 ...

  4. mysql的配置(图解)

    一.配置MySQL数据库 1.解压绿色版mysql,如下图 二.安装服务 1.运行cmd(管理员版本,否则没有权限),如下图 2.运行命令mysqld –install安装服务,如下图: 如果不需要m ...

  5. CDN之多边缘节点负载均衡--学习笔记

    一.剧情 剧情是这样的,本次的多边缘节点负载均衡实验,1个LVS四层负载均衡集群和1个Nginx为反向代理的七层负载均衡集群,由Bind dns解析作为 主负载均衡服务器,调度两个集群,中间层有一台W ...

  6. 关于1.0.0版Backbone.js调用validate

    网上的调用这个方法的例子都是老版本的,新版本的调用方法有所变化,首先错误绑定事件error换成了invalid,其次设置数据时应传入{validate: true} var Chapter = Bac ...

  7. 团队合作的Ground Rules

    在每个Sprint中,我们会为Sprint的确定DOD(Definition of Done,完成的定义).在团队成员合作的过程中,我们也需要定义合作规则,这就是Ground rules,就像小学生守 ...

  8. [iOS]swift之UITableView添加通过xib创建的headerView坑爹问题

    情景是这样的,我UITableView添加了一个HeaderView,这个HeaderView是通过xib创建,是UIView.出来的结果却出乎意料,UITableView的Cell最顶部的几个被He ...

  9. shell编程——变量子串的常用操作

    ${#字符串} 返回字符串的长度 [root@localhost ~]# a=length [root@localhost ~]# echo ${#a} 6 ${字符串:位置x} 从位置x开始往后截取 ...

  10. 将DataTable中的数据导出成Excel

    public bool ExportFile(System.Data.DataTable dt){    SaveFileDialog sfd = new SaveFileDialog();    s ...