MyBatis映射不同Schema下同名表为独立对象的问题排查
问题排查与解决方案
核心问题根源
问题出在MyBatis的resultMap配置逻辑上:
- 初始未配置对象唯一标识,MyBatis仅通过
TABLE_NAME判断对象唯一性,导致两个不同Schema下的同名表被合并成一个对象,列和约束全部混在一起 - 后续仅在Table构造器添加
idArgs,但未在resultMap中明确配置联合唯一标识,导致MyBatis把每一行查询结果都当作新对象,生成了与列数一致的Table实例
正确的ResultMap配置
要让MyBatis以TABLE_SCHEMA+TABLE_NAME的组合作为Table对象的唯一标识,必须在resultMap中把这两个字段配置为<id>节点,而非仅依赖构造器参数。
示例配置代码
<resultMap id="TableResultMap" type="com.yourpackage.Table"> <!-- 配置联合主键,作为Table对象的唯一判定依据 --> <id property="schemaName" column="TABLE_SCHEMA" /> <id property="tableName" column="TABLE_NAME" /> <!-- 表的基础属性映射 --> <result property="engine" column="ENGINE" /> <result property="comment" column="TABLE_COMMENT" /> <!-- 关联列集合,自动聚合同一表下的所有列 --> <collection property="columns" ofType="com.yourpackage.Column"> <id property="columnName" column="COLUMN_NAME" /> <result property="dataType" column="DATA_TYPE" /> <result property="nullable" column="IS_NULLABLE" /> <!-- 其他列属性按需添加 --> </collection> <!-- 关联约束集合,自动聚合同一表下的所有约束 --> <collection property="constraints" ofType="com.yourpackage.Constraint"> <id property="constraintName" column="CONSTRAINT_NAME" /> <result property="constraintType" column="CONSTRAINT_TYPE" /> <!-- 其他约束属性按需添加 --> </collection> </resultMap>
查询语句优化要点
确保查询语句中明确返回TABLE_SCHEMA和TABLE_NAME,且关联INFORMATION_SCHEMA表时严格匹配这两个字段,避免数据关联错误:
SELECT t.TABLE_SCHEMA, t.TABLE_NAME, t.ENGINE, t.TABLE_COMMENT, c.COLUMN_NAME, c.DATA_TYPE, c.IS_NULLABLE, con.CONSTRAINT_NAME, con.CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.TABLES t LEFT JOIN INFORMATION_SCHEMA.COLUMNS c ON t.TABLE_SCHEMA = c.TABLE_SCHEMA AND t.TABLE_NAME = c.TABLE_NAME LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu ON t.TABLE_SCHEMA = kcu.TABLE_SCHEMA AND t.TABLE_NAME = kcu.TABLE_NAME LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS con ON kcu.CONSTRAINT_SCHEMA = con.CONSTRAINT_SCHEMA AND kcu.CONSTRAINT_NAME = con.CONSTRAINT_NAME WHERE t.TABLE_NAME = 'order_items' AND t.TABLE_SCHEMA IN ('unit_test_database_three', 'unit_test_database_two')
关键规则说明
<id>节点是MyBatis判断对象唯一性的核心,只要这两个字段的组合值相同,就会被视为同一个对象,自动聚合对应的列和约束collection标签会根据父对象的唯一标识,将同属一个表的子数据(列、约束)自动归集到对应集合中,不会出现拆分或合并错误- 仅靠构造器的
idArgs无法实现正确的对象聚合,必须在resultMap中显式配置<id>定义唯一标识规则
内容的提问来源于stack exchange,提问作者michal.kyjovsky
相关产品推荐
相关产品推荐

