mysql/jdbc:设置useInformationSchema=true读取表注释信息(table_comment)

本文介绍了解决MySQL中使用Java获取表注释信息返回null的问题。原因是Connector/J的useInformationSchema参数默认为false,导致无法从DatabaseMetaData正确获取表注释。通过设置useInformationSchema=true,可解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#问题描述
今天在读取表的注释信息(COMMENT)时,发现返回的REMARKS字段返回居然是null.
以下是代码示例:

DatabaseMetaData meta = this.pConnection.getMetaData();
// 获取所有表信息
ResultSet resultSet = this.meta.getTables(this.catalog, tableSchema, pattern, this.tableTypes);
while (resultSet.next()) {
	Table table = new Table();
	# 返回null
	String comment=resultSet.getString("REMARKS");
}
resultSet.close();

#原因分析
google找了半天,总算知道原因:
Connector/J 5.0.0以后的版本有一个名为useInformationSchema的数据库连接参数,
在默认连接参数情况下,useInformationSchema=false,导致Connection.getMetaData()方法返回的DatabaseMetaData 对象是com.mysql.jdbc.DatabaseMetaData,而不是com.mysql.jdbc。DatabaseMetaDataUsingInfoSchema,
DatabaseMetaDataUsingInfoSchemaDatabaseMetaData是的子类,看名称就能联想到是通过 INFORMATION_SCHEMA 数据库获取数据库的metadata,可以正确返回table_comment字段。

下面是useInformationSchema的官方说明

useInformationSchema

When connected to MySQL-5.0.7 or newer, should the driver use the INFORMATION_SCHEMA to derive information used by DatabaseMetaData?

Default: false
Since version: 5.0.0
摘自《5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J》

而父类DatabaseMetaData并不一定能正常返回table_comment字段.

关于INFORMATION_SCHEMA 这里不深入探讨,参见《Chapter 24 INFORMATION_SCHEMA Tables》
#解决方法
解决的方法也很简单:
数据库连接时设置useInformationSchema=true
如何设置数据库连接参数呢?有两个途径
##方法一:java代码实现

# 将所有参数装入java.util.Properties 对象
Properties props = new Properties();
props.setProperty("username",this.username);
props.setProperty("password",this.password); 
props.setProperty("useInformationSchema", "true");
# 调用getConnection(String,Properties)方法创建连接
this.pConnection = java.sql.DriverManager.getConnection(this.url, props);

##方法二:连接url参数
直接将参数加到数据库连接url,如下代码中在数据连接url中添加了两个参数characterEncoding=utf8useInformationSchema=true

String url="jdbc:mysql://localhost:3306/test?characterEncoding=utf8&&useInformationSchema=true"
this.pConnection = DriverManager.getConnection(this.url, this.username,this.password);

关于mysql 连接URL的语法参见:
《5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J》

#参考资料
《Connector/J does not retrieve the table comment in a InnoDB table》
《Retrieve mysql table comment using DatabaseMetaData》
《Chapter 24 INFORMATION_SCHEMA Tables》
《5.1 Driver/Datasource Class Names, URL Syntax and Configuration Properties for Connector/J》

<think>好的,我现在需要帮助用户解决一个数据库错误。用户遇到的错误是“Table 'erpmes.page_info' doesn't exist”,这意味着在执行SQL查询时,系统找不到这个。用户之前已经创建了page_info,但现在出现这个问题,可能是什么原因呢? 首先,我应该回顾用户之前的操作。用户之前创建了page_info的结构,并且尝试插入数据。现在在执行SELECT查询时,系统提示该不存在。可能的原因有几个: 1. **未被正确创建**:虽然用户运行了建语句,但可能由于权限问题、语法错误或数据库连接问题,并没有真正创建成功。用户可能在执行建语句时没有注意到错误提示,或者语句在运行时没有生效。 2. **数据库或名大小写问题**:某些数据库系统(如Linux下的MySQL)对名的大小写敏感。用户可能创建的名是Page_Info或page_info,但在查询时使用了不同的拼写方式,导致系统无法识别。需要确认数据库的实际名是否与查询中的一致。 3. **数据库选择错误**:用户可能连接到错误的数据库。例如,建时在数据库A中创建,但查询时却连接到了数据库B,导致不存在。需要检查当前连接的数据库是否是erpmes,并且确认该数据库中确实存在page_info。 4. **事务未提交**:如果用户在使用某些数据库客户端时,建操作在一个未提交的事务中,其他会话可能无法看到这个。需要确认建操作已经提交,或者重新连接数据库以查看是否存在。 接下来,我需要为用户提供具体的解决步骤: 首先,验证是否存在。用户可以通过执行SHOW TABLES命令来查看当前数据库中是否存在page_info。如果不存在,可能需要重新运行建语句。这时要检查建语句是否有语法错误,比如注释中的引号是否正确使用,是否使用了中文引号导致解析错误。 其次,检查数据库连接配置。用户的应用可能在连接数据库时指定了不同的数据库名,或者连接字符串有误,导致应用尝试访问错误的数据库。需要确认应用的配置文件(如JDBC URL)中的数据库名称是否正确。 另外,检查名的大小写。如果数据库系统区分大小写,而建时的名和查询时的名大小写不一致,也会导致错误。建议统一使用小写名,并在查询时保持一致。 还有,检查数据库权限。用户可能没有在目标数据库上创建的权限,或者当前用户没有访问该的权限。需要确保数据库用户拥有足够的权限执行建和查询操作。 此外,查看应用程序的日志或错误信息,确认具体的SQL语句是否正确,是否有拼写错误或其他语法问题。例如,检查PageInfoMapper.xml文件中的SQL语句,确认名是否正确,是否有特殊字符未被正确转义。 最后,如果问题仍然存在,可能需要重启数据库服务或应用服务器,以确保所有更改生效,或者联系数据库管理员进一步排查问题。 用户可能在之前的操作中忽略了某个步骤,比如建后没有提交事务,或者在分布式环境中不同节点的数据库未同步。需要一步步引导用户进行验证,从最基本的是否存在开始,逐步排查可能的原因,确保每个环节都正确无误。</think>--- ### 错误原因分析 报错信息 `Table 'erpmes.page_info' doesn't exist` 明: 1. **未被正确创建**:虽然之前提供了建语句,但可能未实际执行成功(例如权限不足、语法错误或执行环境问题)。 2. **名大小写敏感**:某些数据库系统(如Linux环境下的MySQL)对名大小写敏感,需确认实际名是否为 `page_info`。 3. **数据库未正确选择**:可能连接到错误的数据库(例如当前数据库不是 `erpmes`)。 --- ### 分步解决方案 #### 第一步:验证是否存在 ```sql -- 检查数据库中的 USE erpmes; SHOW TABLES LIKE 'page_info'; -- 查看结构(若存在) DESC page_info; ``` - **预期结果**:应返回 `page_info` 的字段结构。 - **若不存在**:需重新执行建语句(检查语法和权限)。 --- #### 第二步:重新执行建语句 确认建语句无语法错误(特别注意中文字符引号): ```sql -- 修正后的建语句(确保使用英文引号) CREATE TABLE page_info ( page_id INT UNSIGNED AUTO_INCREMENT COMMENT '页面ID', column_name VARCHAR(255) NOT NULL COMMENT '栏目名称', page_name VARCHAR(255) NOT NULL COMMENT '页面名称', is_show BOOLEAN NOT NULL DEFAULT FALSE COMMENT '显示状态', PRIMARY KEY (page_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci COMMENT='页面信息'; ``` --- #### 第三步:检查数据库连接配置 1. **确认应用连接的数据库** 检查应用配置文件(如 `application.yml` 或 `application.properties`)中的数据库名称是否为 `erpmes`: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/erpmes?useSSL=false ``` 2. **验证数据库用户权限** 确保当前数据库用户拥有 `erpmes` 库的访问权限: ```sql -- 查看用户权限 SHOW GRANTS FOR 'your_username'@'localhost'; ``` --- #### 第四步:排查大小写敏感问题 1. **检查操作系统和数据库配置** - Linux 系统默认对名大小写敏感,需确认实际名是否为小写 `page_info`。 - 查看 MySQL 配置参数: ```sql SHOW VARIABLES LIKE 'lower_case_table_names'; ``` - 若值为 `0`:名大小写敏感,需严格匹配。 - 若值为 `1`:名存储为小写,不敏感。 2. **统一名大小写** 在 SQL 语句中强制使用小写名: ```sql SELECT column_name FROM `page_info`; -- 使用反引号包裹 ``` --- #### 第五步:检查事务提交或连接会话 1. **确认建操作已提交** 如果使用命令行或工具(如MySQL Workbench),需确保执行建语句后已提交事务。 2. **重启数据库连接** 某些情况下需重新连接数据库以刷新元数据缓存。 --- ### 验证流程 1. **执行查询验证** ```sql -- 查询数据是否可正常读取 SELECT * FROM page_info; ``` 2. **检查应用日志** 若仍报错,查看应用日志中完整的 SQL 语句,确认是否存在转义或拼接错误。 --- ### 常见问题总结 | 问题类型 | 现 | 解决方案 | |---------|------|---------| | 未创建 | `SHOW TABLES` 无结果 | 重新执行建语句 | | 权限不足 | 用户无库/权限 | 授权 `GRANT` | | 大小写敏感 | 名实际为 `Page_Info` | 统一使用小写 | | 数据库未切换 | 连接至其他库 | 执行 `USE erpmes` | 建议从基础排查开始,逐步验证每个环节。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

10km

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值