背景
控制台提示报错:
Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Connections could not be acquired from the underlying database!
后台日志报错中出现:com.mysql.cj.exceptions.WrongArgumentException: Malformed database URL, failed to parse the connection string near '=utf-8;serverTimezone=Asia/Shanghai'.
解决办法
这一段数据库的连接本身是没有什么问题,将原来mysql-connector-java jar版本从8.0.11换成8.0.15就解决了
原因分析
我在想jar版本换了就能解决问题,那不同版本之间肯定有比较大的差距。后来看到
mysql-connector-java的版本在8.0.12也有这个问题,到8.0.13才解决,那到底是什么原因导致的呢?通过调试jar包程序,发现在解析url时用到的正则表达式发生了调整,具体差异如下:
这两个正则表达式非常相似,都用于解析查询字符串或者HTTP请求参数格式的键值对,比如key=value&another_key=value2这样的形式。两者主要区别在于对“值”部分(<value>组)的定义上。
共同点:
(?<key>[\w.\-\s%]*) 部分都是一样的,用来捕获键名,允许包含字母、数字、下划线、点、破折号和空白字符(包括空格)。
区别:
第一个正则表达式:[^&=]*
这个片段表示“值”的部分可以包含除&和=之外的任何字符的任意次数,这意味着它可以匹配到不包含&和=的值,即使值中包含了特殊字符。
第二个正则表达式:[^&]*
这个片段表示“值”的部分可以包含除&之外的任何字符的任意次数,但不禁止=的存在。因此,在这个表达式下,值可以包含=, 但它不能包含&,因为一旦遇到&,正则表达式就会停止匹配值部分。
总结起来,第一个表达式更严格地限制了值的部分,不允许出现=作为值的一部分;而第二个表达式则允许值中包含=符号,但不允许值中包含&。在处理URL查询字符串时,通常值中是可以包含=的,因为它用于分隔键和值,所以第二个表达式可能更适合用于解析实际的HTTP查询字符串参数。
补充说明
mysql官方对上面的问题做了如下解释说明:
https://dev.mysql.com/doc/relnotes/connector-j/8.0/en/news-8-0-13.html
这段话的意思大致是:
当连接属性的值本身包含等号(“=”)时,会引发异常(“WrongArgumentException:数据库URL格式不正确”)。这是由于连接URL的解析程序中出现错误,此修复程序已更正该错误。