MyBatis3查询含特殊字段表报错:String类无'1'属性setter方法
MyBatis查询含点号列名时触发ReflectionException的问题解决
问题现象
查询某客户表全量数据时抛出异常:
org.apache.ibatis.reflection.ReflectionException: Could not set property '1' of 'class java.lang.String' with value '0'
根源是Java的String类不存在名为1的属性setter方法。
复现环境与步骤
- MyBatis版本:3.5.17
- MySQL版本:5.6(问题与数据库类型无关)
- 创建测试表:
CREATE TABLE `test_1` ( `账单号` varchar(255) COMMENT 'null', `账单号.1` varchar(255) DEFAULT NULL COMMENT 'null' ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- 插入测试数据:
INSERT INTO `test_1` VALUES ('0','0');
- 使用MyBatis执行全量查询(如
SELECT * FROM test_1),触发上述异常。
原因分析
MyBatis的BeanWrapper组件在处理结果映射时,会将列名中的点号(.)解析为对象属性的层级访问符。对于列名账单号.1,它会错误地认为账单号是一个对象类型的属性,而1是该对象的子属性,尝试调用String类的set1()方法赋值,这显然不符合逻辑,因此抛出反射异常。
解决方案
方案1:SQL查询时给特殊列名加别名
在查询SQL中为含点号的列指定别名,避免MyBatis解析层级关系:
SELECT `账单号`, `账单号.1` AS 账单号_1 FROM test_1;
同时确保实体类中存在与别名对应的属性(如private String 账单号_1;及对应的getter/setter)。
方案2:使用ResultMap明确映射关系
通过自定义ResultMap,直接指定列名与实体属性的对应关系,跳过自动解析:
<resultMap id="Test1ResultMap" type="com.yourpackage.Test1Entity"> <result column="账单号" property="账单号"/> <result column="账单号.1" property="账单号1"/> </resultMap> <select id="selectAll" resultMap="Test1ResultMap"> SELECT * FROM test_1 </select>
实体类中对应属性为private String 账单号1;(或其他合法属性名)。
方案3:修改列名(若允许)
如果业务场景允许,直接修改数据库列名,移除点号等特殊字符,比如改为账单号_1,从根源避免解析问题。
内容的提问来源于stack exchange,提问作者Levin Xiao
相关产品推荐
相关产品推荐

