ibatis中得resultMap得property属性值得大小写

总结

今天在公司写代码过程中,一不小心把sql得xml中得resultMap得property属性值得首字母写成大写,导致编译报错。百思不得其解,现我做几个实验来验证我的想法。

准备一个实体类和一段sql

User实体类

package com.jsyy.jrsc.entity;

public class User {
    private int id;
    private String user_name;
    private String user_no;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUser_name() {
        return User_name;
    }

    public void setUser_name(String user_name) {
        this.User_name = user_name;
    }

    public String getUser_no() {
        return user_no;
    }

    public void setUser_no(String user_no) {
        this.user_no = user_no;
    }
}

执行sql返回结果集的封装

<resultMap id="userResult" class="user" >
        <result column="id" property="id" jdbcType="INTEGER" />
        <result column="user_name" property="user_name" jdbcType="VARCHAR" />
        <result column="user_no" property="user_no" jdbcType="VARCHAR" />
</resultMap>

实验一:改变实体类的大小写

改变User实体类里面的属性user_name的首字母U,换成大写。启动项目编译成功

七月 10, 2020 9:47:49 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service [Tomcat]
七月 10, 2020 9:47:49 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet engine: [Apache Tomcat/9.0.35]
七月 10, 2020 9:47:49 下午 org.apache.catalina.core.ApplicationContext log
信息: Initializing Spring embedded WebApplicationContext

实验二:改变sql的resultMap的property属性值得大小写

把user_name改成User_name

 <result column="user_name" property="User_name" jdbcType="VARCHAR" />

编译报错

Caused by: java.lang.RuntimeException: 加载sqlmap-文件出错(load sqlmap- file wrong). Cause: java.lang.RuntimeException: Error occurred. Cause: com.ibatis.common.xml.NodeletException: Error parsing XML. Cause: java.lang.RuntimeException: Error parsing XPath ‘/sqlMapConfig/sqlMap’. Cause: com.ibatis.common.xml.NodeletException: Error parsing XML. Cause: java.lang.RuntimeException: Error parsing XPath ‘/sqlMap/resultMap/result’. Cause: com.ibatis.common.beans.ProbeException: There is no WRITEABLE property named ‘User_name’ in class ‘com.jsyy.jrsc.entity.User’

结论

实体类属性的无论是大小写还是驼峰,都不会影响。但是sql结果集中的property属性值必须要小写

深入底层分析

这个报错并不是在封装结果集的时候报的错,因为编译时候并不会执行sql。只有请求打过来,执行sql,采取封装结果集。而且我看了源码更加确定这一点。

 // 字段名
 String columnName = metaData.getColumnName(i);
 // 字段的值
 Object value = resultSet.getObject(columnName);
//使用反射或者内省,根据数据库表和实体的对应关系,完成封装
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, resultTypeClass);
Method writeMethod = propertyDescriptor.getWriteMethod();
writeMethod.invoke(o,value);

最后的猜测

我没把整个源码都放过来,但是看value的值通过反射来获取,然后通过内省方法,set+首字母大写转换(“value”),查找对应字符串的方法,然后反射调用方法,把属性set进去。
编译报错,应该是解析xml的时候报错,我猜测,在解析到resultMap的时候,自动把属性值转成user_name而非User_name,然后再到实体类里面找这个属性值,发现没有,然后抛异常。个人猜测,没有去验证和深入底层再去看,如果有什么不对的地方,请各位大佬提出,万分感谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值