多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
Java 应用连接 MySQL 8 数据库遇到以下问题: ~~~dart 2020-07-13 15:28:58 WARN 14972 --- [xec-9] i.SqlExceptionHelper137 : SQL Error: 1055, SQLState: 42000 2020-07-13 15:28:58 ERROR 14972 --- [xec-9] i.SqlExceptionHelper142 : (conn=10930) Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'a.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by 2020-07-13 15:28:58 ERROR 14972 --- [xec-9] ller.aop.ValidateAop64 : could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet ~~~ 分析: `ONLY_FULL_GROUP_BY` 的意思是针对 `GROUP BY` 聚合操作,如果 `SELECT` 中的列没有在 `GROUP BY` 中出现,那么这个 SQL 是不合法的,因为列不在 `GROUP BY` 从句中。 解决方案一: 使用 MySQL 客户端查询 `sql_mode`,发现包含 `ONLY_FULL_GROUP_BY`,使用 `SET` 命令更新,然后再次查询发现 `ONLY_FULL_GROUP_BY` 已不存在。 ~~~csharp mysql> SELECT @@global.sql_mode; +-----------------------------------------------------------------------------------------------------------------------+ | @@global.sql_mode | +-----------------------------------------------------------------------------------------------------------------------+ | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | +-----------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> SET @@global.sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT @@global.sql_mode; +----------------------------------------------------------------------------------------------------+ | @@global.sql_mode | +----------------------------------------------------------------------------------------------------+ | STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION | +----------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> USE DB_NAME Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> SET sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; Query OK, 0 rows affected (0.00 sec) ~~~ 注意: 1. `SET @@global.sql_mode` 修改了全局 `sql_mode`,只对新建的数据库生效,对于已经存在的数据库,需要使用 `USE` 命令先切换到具体数据库,然后执行 `SET sql_mode` 命令; 2. 这种方案在 MySQL 服务重启后会失效,即重启后 `ONLY_FULL_GROUP_BY` 还会出现。 解决方案二: 修改 MySQL 配置文件,Windows 操作系统中为 `my.ini` 文件,Linux 操作系统中使用 RPM 安装包安装后配置文件位于 `/etc/my.cnf`。 在 `[mysqld]` 添加: ~~~undefined sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION ~~~ 重启 MySQL 服务。