千家信息网

怎么解决mybatis报Invalid value for getInt()的问题

发表于:2025-02-04 作者:千家信息网编辑
千家信息网最后更新 2025年02月04日,这篇文章主要介绍"怎么解决mybatis报Invalid value for getInt()的问题",在日常操作中,相信很多人在怎么解决mybatis报Invalid value for getIn
千家信息网最后更新 2025年02月04日怎么解决mybatis报Invalid value for getInt()的问题

这篇文章主要介绍"怎么解决mybatis报Invalid value for getInt()的问题",在日常操作中,相信很多人在怎么解决mybatis报Invalid value for getInt()的问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"怎么解决mybatis报Invalid value for getInt()的问题"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

背景

使用mybatis遇到一个非常奇葩的问题,错误如下:

Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'name' from result set. Cause: java.sql.SQLException: Invalid value for getInt() - 'wo'

场景

还原一下当时的情况:

public interface UserMapper {    @Results(value = {            @Result(property = "id", column = "id", javaType = Long.class, jdbcType = JdbcType.BIGINT),            @Result(property = "age", column = "age", javaType = Integer.class, jdbcType = JdbcType.INTEGER),            @Result(property = "name", column = "name", javaType = String.class, jdbcType = JdbcType.VARCHAR)    })    @Select("SELECT id, name, age FROM user WHERE id = #{id}")    User selectUser(Long id);}@Data@Builderpublic class User {    private Long id;    private Integer age;    private String name;}public class MapperMain {    public static void main(String[] args) throws Exception {        MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();        dataSource.setUser("root");        dataSource.setPassword("root");        dataSource.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8");        TransactionFactory transactionFactory = new JdbcTransactionFactory();        Environment environment = new Environment("development", transactionFactory, dataSource);        Configuration configuration = new Configuration(environment);        configuration.addMapper(UserMapper.class);        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);        try (SqlSession session = sqlSessionFactory.openSession()) {            UserMapper userMapper = session.getMapper(UserMapper.class);            System.out.println(userMapper.selectUser(1L));        }    }}

数据库如下:

上面是一个很简单的例子,就是根据id选出用户的信息,运行结果如下:

User(id=1, age=2, name=3)

没有任何问题,但是我再往数据库里插入一条数据,如下:

MapperMain类中增加一行代码,如下:

System.out.println(userMapper.selectUser(2L));

运行结果如下:

User(id=1, age=2, name=3)
### Error querying database. Cause: org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'name' from result set. Cause: java.sql.SQLException: Invalid value for getInt() - 'lh'
……

可以看出第一条查询没有问题,第二条查询就报错了

初探

其实我的直觉告诉我,是不是因为User类里字段顺序和SQL语句里select字段的顺序不一致导致的,那就来试一下吧

改一下User类里字段的顺序:

@Data@Builderpublic class User {    private Long id;    private String name;    private Integer age;}

结果如下:

User(id=1, name=3, age=2)
User(id=2, name=lh, age=3)

果不其然,直觉还是很6的

或者改一下SQL语句里select字段的顺序:

@Data@Builderpublic class User {    private Long id;    private Integer age;    private String name;}public interface UserMapper {    @Results(value = {            @Result(property = "id", column = "id", javaType = Long.class, jdbcType = JdbcType.BIGINT),            @Result(property = "age", column = "age", javaType = Integer.class, jdbcType = JdbcType.INTEGER),            @Result(property = "name", column = "name", javaType = String.class, jdbcType = JdbcType.VARCHAR)    })    @Select("SELECT id, age, name FROM user WHERE id = #{id}")    User selectUser(Long id);}

以我们的直觉,结果肯定也没问题,果不其然,如下:

User(id=1, age=2, name=3)User(id=2, age=3, name=lh)

再探

其实到上一步,问题已经解决了,可以继续干活了,但是搞不懂为什么,心里总觉得不踏实。

bugdebug开始,从下面的入口开始:

追踪到如下:

可以看出User这个类是有构造函数的,而且是包含所有字段的构造函数
利用这个构造函数创建实例的时候,参数的顺序就是SQL语句选择字段的顺序,不会根据映射关系去选择
所以就出现了类型不匹配

那我们再来看一下问什么会有一个这样的构造函数产生,直觉告诉我是@Builder这个注解

一起来看一下User编译后的结果:

public class User {    private Long id;    private String name;    private Integer age;    User(final Long id, final String name, final Integer age) {        this.id = id;        this.name = name;        this.age = age;    }    public static User.UserBuilder builder() {        return new User.UserBuilder();    }    public static class UserBuilder {        private Long id;        private String name;        private Integer age;        UserBuilder() {        }        public User.UserBuilder id(final Long id) {            this.id = id;            return this;        }        public User.UserBuilder name(final String name) {            this.name = name;            return this;        }        public User.UserBuilder age(final Integer age) {            this.age = age;            return this;        }        public User build() {            return new User(this.id, this.name, this.age);        }    }}

果然如此,UserBuilder.build()方法就是利用这个构造函数来生成的。

结局

最终解决方案就是给User类加上无参的构造函数就OK了,如下:

@Builder@AllArgsConstructor@NoArgsConstructorpublic class User {    private Integer age;    private String name;    private Long id;}

字段顺序随便放,最后再执行一下:

User(age=2, name=3, id=1)User(age=3, name=lh, id=2)

到此,关于"怎么解决mybatis报Invalid value for getInt()的问题"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

问题 字段 顺序 函数 结果 就是 直觉 学习 数据 语句 果不其然 数据库 方法 更多 帮助 查询 运行 选择 一致 踏实 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 数据库操作权限 免服务器小程序带流量主 多买网络技术有限公司好不好 金乡县迎锋网络技术有限公司 投影融合拼接服务器快捷键 系统网络安全近期价格 郑州办公系统软件开发大概多少钱 纳雍县校园网络安全管理制度 数据库中删除表格的代码 抢购软件开发手机端 诺基亚5g网络技术 网络安全保险第三方公司 gta本地目录无法同步服务器 钱江潮时间表软件开发 中兴通讯网络安全扫描工具 中国商品诚信数据库电话 冠科网络技术公司 计算机网络技术4000电脑 王者更换服务器还能换回去嘛 工行软件开发中心和信用社 南京运营软件开发诚信服务 千方百计医药软件开发 网络安全小报手抄报模版 mysql数据库怎么改id 陕西软件开发发展 洛奇英雄传手游服务器 保护数据库安全五种关键技术 网络安全检测评估准则 数据库包含哪几类数据文件 传统文化对网络安全工作的
0