Error attempting to get column 'e_gender' from result set

今天在使用mybatis查询时遇到报错

Error attempting to get column 'e_gender' from result set.  Cause: java.sql.SQLException: Cannot convert value '男' from column 3 to TIMESTAMP.
; Cannot convert value '男' from column 3 to TIMESTAMP.; nested exception is java.sql.SQLException: Cannot convert value '男' from column 3 to TIMESTAMP.

在网上查了很多解决办法,大多都是说是数据库字段类型与实体类的属性类型的定义不一致的原因,但是请看:

<resultMap type="com.xyw.hospital.model.entity.Employee" id="BaseMap">
        <result property="eId" column="e_id" jdbcType="INTEGER"/>
        <result property="eName" column="e_name" jdbcType="VARCHAR"/>
        <result property="eGender" column="e_gender" jdbcType="VARCHAR"/>
        <result property="eBirthday" column="e_birthday" jdbcType="TIMESTAMP"/>
        <result property="eDid" column="e_did" jdbcType="INTEGER"/>
        <result property="eRoleid" column="e_roleid" jdbcType="INTEGER"/>
        <result property="eTel" column="e_tel" jdbcType="VARCHAR"/>
        <result property="eVprice" column="e_vprice" jdbcType="NUMERIC"/>
        <result property="eState" column="e_state" jdbcType="INTEGER"/>
        <result property="eCreateTime" column="e_create_time" jdbcType="TIMESTAMP"/>
        <result property="eClossTime" column="e_closs_time" jdbcType="TIMESTAMP"/>
    </resultMap>

    <sql id="items">
        e_id, e_name, e_gender, e_birthday, e_did, e_roleid, e_tel, e_vprice, e_state, e_create_time, e_closs_time    </sql>
    <!--查询单个-->
    <select id="queryById" resultMap="BaseMap">
        select
          <include refid="items"/>
        from employee
            where e_id = #{eId}
    </select>
CREATE TABLE `employee` (
  `e_id` int(11) NOT NULL AUTO_INCREMENT,
  `e_name` varchar(25) DEFAULT NULL,
  `e_gender` varchar(4) DEFAULT NULL COMMENT '''男''或''女''',
  `e_birthday` date DEFAULT NULL,
  `e_did` int(11) DEFAULT NULL,
  `e_roleid` int(11) DEFAULT NULL,
  `e_tel` varchar(15) DEFAULT NULL,
  `e_vprice` decimal(10,2) DEFAULT NULL,
  `e_state` int(1) DEFAULT '0' COMMENT '0 新注册(默认) 1 在职 2离职',
  `e_create_time` date DEFAULT NULL,
  `e_closs_time` date DEFAULT NULL,
  PRIMARY KEY (`e_id`) USING BTREE,
  KEY `idx_did` (`e_did`) USING BTREE,
  KEY `idx_roleid` (`e_roleid`) USING BTREE,
  KEY `idx_state` (`e_state`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
	protected Integer eId;
    protected String eName;
    protected String eGender;
    protected Date eBirthday;
    protected Integer eDid;
    protected Integer eRoleid;
    protected String eTel;
    protected Double eVprice;
    protected Integer eState;
    protected Date eCreateTime;
    protected Date eClossTime;

    public Employee(String eName, String eGender, Date eBirthday, String eTel, Integer eDid, Integer eRoleid, Double eVprice) {
        //略
    }

可以看到字段定义一致,导致一致我一直不得其解。

这个地方真正的原因是什么呢?

大家也许已经看到了,我这里有个构造方法,其中省去了一个字段,导致查到的数据多余构造方法中的数据,使得其将e_id->eName,e_name->eGender,e_gender->eBirthday,这里因为e_gender是vchar,而eBirthday是date类型,导致的类型转换失败。

这里又回到类型问题了,关于类型转换的问题这里不详说。但是大家记得在定义数据库字段与实体类字段的类型一定要一致

而这里的问题就在于mybatis在进行赋值时会使用实体类的构造方法进行赋值,如果构造方法中的参数个数与mysql结果集中的字段数量不一致时,特别是少了前面的参数,赋值时会按照顺序进行赋值,就有可能会出错。

这里的解决办法很简单,只要在实体类中添加一个空的构造方法

public Employee() {
    }

即可,mybatis会优先使用最适合的构造方法进行赋值,如果找不到适合的构造方法,就会使用空的构造方法,在赋值时会从实体类的属性中查找与结果集中字段名相同的属性进行赋值。

这让我想起以前在刚学习javaweb时老师总是强调空的构造方法的重要性,却始终不能理解,这次的出错让我记得以后对于pojo类的定义时,如果需要定义有参的构造方法,一定要把无参构造方法给补上,防止出现类似问题。

以上都是本人自己的理解,可能会与真正的解答不一致,欢迎各位大佬指正。

扫描二维码关注公众号,回复: 10515940 查看本文章

猜你喜欢

转载自www.cnblogs.com/xywang-35/p/12640000.html