【Springboot项目】记录mybatis常见异常及处理方法

1.in 导致的异常

 Data truncation: Truncated incorrect DOUBLE value:

异常过程:

mapper 接口如下:

public int updateBatchId(@Param("batchId")String batchId,@Param("idStr")String idStr);

xml 中 sql 如下:

    <update id="updateBatchId" parameterType="java.lang.String">
        update pdm_description_error_msg set batch_id = #{batchId},status = "1",process_num = process_num +1
        where id in (#{idStr})
    </update>

原因分析:

mybatis 中 in 不能这样写,需要使用 foreach, 不然就会报如上的错误。

解决办法:(这里的 idStr 是以逗号分隔的,形式是这样的:1,2,3,4)

    <update id="updateBatchId" parameterType="java.lang.String">
        update pdm_description_error_msg set batch_id = #{batchId},status = "1",process_num = process_num +1
        where id in
        <foreach item="item" index="index" collection="idStr.split(',')" open="(" separator="," close=")">
            '${item}'
        </foreach>
    </update>

异常总结

之前写 sql 时是使用注解的方式写的,通过那种方式,在 java 代码中是可以直接使用以逗号分隔的字符串的,例子如下:

    public String updateBatchId(String batchId,String idStr){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("update pdm_error_msg set batch_id = '" + batchId + "',status=1,process_num=process_num+1 where " +
                " (status=0 or status = 3) and id in ("+idStr+")");
        return stringBuilder.toString();
    }

这个是在 java 中直接拼接的 sql 可以,可以直接使用带逗号的字符串,在 xml 不行。

2.group_concat

这个 mysql 中关键字其实一般是不会使用的,但是有时使用 group by 做分组的时候,又希望把分组的结果拿出来,就可能会使用这个关键字,但是,重点是这个但是,如果返回的字段的长度过长,就会直接截断,然后也不抛异常,然后返回出来的结果就是一个阶段后的结果。

为啥要截断呢?

mysql 为了优化性能

那多长会截断呢?

默认就是 1024 个字节,这才多长啊。

能不能避免不被截断?

可以,不过需要 mysql 的权限,让 dba 设置,不过 dba 爸爸估计不会帮这个忙

总结

严格来说这个锅不是 mybatis 的锅,其实是 mysql 为了优化性能搞的,举个例子,如果你程序开发测试环境随便造的数据,都很短,没问题,当部署到生产环境,运行一段时间,出问题,那估计问题就很严重。

3.is not null 和 !=    ;    is null 和 =

这个在平时写 sql 的时候一般没什么问题,遇见 null 值判断,都会使用 is, 或者 is not,但是偶尔会写成!=,这就搞飞机了,写成这样 sql 也不会抛异常,但是就是统计的数据不准确。原因就是 null 值不能使用 =,!=,<> 等判断。

4.provider 中 sql 语句把反斜线去掉,导致的转义问题

更新于 --------------------------------------2020-01-15---------------------------------------

springboot 中使用 mybatis,现在很多小伙伴都不使用 xml 的方式写 sql 了,而是通过 provider,如果牵涉到批量操作,基本上大家都不会直接在 mapper 中写 sql,而是在 provider 中通过字符串拼接的方式来实现 sql,这个写一般的 sql 没什么问题,一旦遇见一些坑爹的场景其实还是 xml 的方式比较好,比如下面说的问题:

场景:把表 A 中的 message 字段批量读出来,一次读取 100 条,批量插入到表 B,实现方式是在 provider 中实现字符串拼接

代码如下:

public String insertCheckMsgBatch(List<CheckMsg> msgList) {
        StringBuffer sql = new StringBuffer();
        sql.append("insert into table(message,status) values ");

        if(!CollectionUtils.isEmpty(msgList)) {
            int i = 0;
            for(CheckMsg msg : msgList) {
                i++;
                sql.append("("+msg.getMessage()+","+msg.getStatus());

                if(i < msgList.size()) {
                    sql.append("),");
                } else {
                    sql.append(")");
                }
            }
        }

        return sql.toString();
    }

出现的问题:由于表 A 中的 message 带有转义字符,会把字符串中的单引号和双引号转义,但是被上面一搞,所有的转义字符都没了,比如  ""abc'"经过这玩意一搞变成了""abc'", 但是这个也可以正常插入数据库,但是下次读出来就会出问题,因为这是一个异常的字符串。

解决办法:

上面问题的根源在于通过 provider 没有经过 PreparedStatement 预编译,如果经过这个预编译 mybatis 其实是可以处理这些特殊的字符的,ok,那就想办法让 mybatis 预编译,有两种方法,一种是改成 xml 方式,这种还要改,麻烦,另一个种是直接通过在 mapper 文件中写批处理 sql 的方式,这种实际和在 xml 一样。如下:

 @Insert({"<script>" +
            "insert into table(message,status) values " +
            "<foreach item='item' index='index' collection='msgList' separator=','> " +
            "(#{item.message},#{item.status})" +
            "</foreach>" +
            "</script>"})
    public int insertMsgBatch(@Param("msgList") List<Msg> msgList);

这样就可以解决问题了,记录一下


作者: 猿起缘灭

来源链接:

https://www.cnblogs.com/gunduzi/p/11890761.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
构建Spring Boot + MyBatis框架是一种常见的Java Web开发方式,它结合了Spring Boot框架和MyBatis持久层框架,可以快速搭建一个高效、可扩展的Web应用程序。下面是构建这个框架的一般步骤: 1. 创建Spring Boot项目:使用Spring Initializr或者IDE工具创建一个新的Spring Boot项目,选择所需的依赖项,包括Spring Web和MyBatis等。 2. 配置数据库连接:在application.properties或application.yml文件中配置数据库连接信息,包括数据库URL、用户名、密码等。 3. 创建实体类:根据数据库表结构创建对应的实体类,使用注解标记实体类与数据库表的映射关系。 4. 创建Mapper接口:创建Mapper接口,定义数据库操作的方法,使用注解标记SQL语句与方法的映射关系。 5. 创建Mapper XML文件:在resources目录下创建Mapper XML文件,编写SQL语句,与Mapper接口中的方法对应。 6. 配置MyBatis:在application.properties或application.yml文件中配置MyBatis相关的配置,包括Mapper XML文件的路径等。 7. 编写Service层:创建Service接口和实现类,定义业务逻辑,并调用Mapper接口中的方法进行数据库操作。 8. 编写Controller层:创建Controller类,处理HTTP请求,并调用Service层的方法进行业务处理。 9. 运行测试:编写单元测试用例,测试各个层的功能是否正常。 10. 部署和发布:将项目打包成可执行的JAR文件或WAR文件,部署到服务器上,并启动应用程序。 以上是构建Spring Boot + MyBatis框架的一般步骤,当然在实际开发中还会涉及到其他方面的内容,比如事务管理、异常处理、日志记录等。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值