帮朋友分析一个spring boot项目无法启动的问题,该项目在启动的时候报了错误 java.sql.SQLException: Unknown system variable ‘query_cache_size’ 。出现这个问题的原因是因为数据库驱动程序与数据库版本不对应。一般情况都是数据库版本较高,而数据库驱动较低造成的不匹配。解决思路是下载与数据库版本适配的mysql-connecter-java驱动版本。
1、程序启动报MYSQL异常
在java程序启动(springboot或一般应用程序)时报以下错误。
java.sql.SQLException: Unknown system variable 'query_cache_size'
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:959)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3870)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3806)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2470)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2617)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2546)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2504)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1370)
at com.mysql.jdbc.ConnectionImpl.loadServerVariables(ConnectionImpl.java:3861)
at com.mysql.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:3289)
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2298)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2084)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:795)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:44)
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:400)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:327)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
在排查问题后发现,以上错误是因为mysql数据库是 8.0 版本,而应用程序的数据库驱动 mysql-connecter-java 的版本过低,为 5.1.37 版本,很显然是数据库驱动程序与数据库版本不对应。只需要更换 mysql-connecter-java 驱动版本为 8.0 的即可。
官方的说法是 :
- The query cache is deprecated as of MySQL 5.7.20, and is removed in MySQL 8.0. Deprecation includes query_cache_size.
意思是query cache在MySQL5.7.20就已经过时了,而在MySQL8.0之后就已经被移除了。
2、解决方案
2.1 方案一:下载mysql驱动8.0版本
如果你的项目是通过引入jar包的方式使用驱动的,可以通过mysql官网下载 mysql-connecter-java-8.0驱动,下载的 mysql-connector-java-8.0.20.tar.gz
解压后,将其中的 mysql-connector-java-8.0.20.jar
放入java项目的lib目录下。
- mysql8.0驱动官网下载地址:mysql-connector-java-8.0.20.tar.gz
解压下载后的压缩包:
将解压后的 mysql-connector-java-8.0.20.jar
放入java项目的lib目录下。
在idea或eclipse中导入这个jar(如果已经设置了引用lib目录下的所有文件,这步可以省略)
2.2 方案二:使用maven的项目更改mysql驱动的版本号
如果你使用的是maven,则更改配置pom.xml文件中的mysql驱动的版本。如下:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
然后右键项目选择maven–>更新maven(或者在maven配置上右键Reload),重启项目,即可解决问题。
或
如果使用的是gradle,同理。
至此,该问题完美解决。
3、拓展:Mysql驱动5和8的配置比较
3.1 mysql8的配置
驱动包:com.mysql.cj.jdbc.Driver
连接串(需要增加时区):jdbc:mysql://localhost:3306/database_name?user=root&password=111111&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
- serverTimezone的值还可以设置为:GMT%2B8
3.2 mysql5的配置
驱动包:com.mysql.jdbc.Driver
连接串:jdbc:mysql://localhost:3306/database_name?user=root&password=111111&useSSL=false&useUnicode=true&characterEncoding=utf-8
在使用数据库连接池的情况下,最好设置如下两个参数:
- autoReconnect=true&failOverReadOnly=false
- 需要注意的是,在xml配置文件中,url中的&符号需要转义。
3.3 mysql的 url参数详解
参数名 | 含义 | 通常取值 |
---|---|---|
user | 数据库用户名(用于连接数据库) | ----- |
passWord | 用户密码(用于连接数据库) | ----- |
useSSL | useSSL 5.7.17版本服务器默认是true 如果不使用SSL连接就要在urL中设置useSSL=false | false |
useUnicode | 是否使用Unicode字符集,如果参数characterEncoding设置为gb2312或gbk,本参数值必须设置为true | true |
characterEncoding | 当useUnicode设置为true时,指定字符编码。比如可设置为gb2312或gbk | utf8 |
serverTimezone | 用于设置时区时间 | Asia/Shanghai |
autoReconnect | 当数据库连接异常中断时,是否自动重新连接? | ----- |
autoReconnectForPools | 是否使用针对数据库连接池的重连策略 | ----- |
maxReconnects | autoReconnect设置为true时,重试连接的次数 | ----- |
failOverReadOnly | 自动重连成功后,连接是否设置为只读? | ----- |
zeroDateTimeBehavior | exception:默认值,即抛出SQL state [S1009]. Cannot convert value…的异常 convertToNull:将日期转换成NULL值;round:替换成最近的日期即0001-01-01 | convertToNull |
评论区