关于MyBatisSystemException异常产生的原因及解决过程

 更新时间:2025年01月23日 17:14:57   作者:宣布无人罪  
文章讲述了在使用MyBatis进行数据库操作时遇到的异常及其解决过程,首先考虑了事务问题,但未解决,接着怀疑是MyBatis的一级缓存问题,关闭缓存后问题依旧存在,最终发现是SQL映射文件中的参数传递错误,使用了错误的标签导致循环插入

MyBatisSystemException异常产生原因及解决

异常发生场景

  • 当我使用mybatis对数据库操作时报的错误
<resultMap id="shoppingCartProduct" type="shoppingCartProductVo">
        <id property="shoppingCartId" column="shopping_cart_id"></id>
        <result property="productId" column="product_id"></result>
        <result property="num" column="num"></result>
        <result property="productName" column="product_name"></result>
        <result property="productTitle" column="product_title"></result>
        <result property="productIntro" column="product_intro"></result>
        <result property="productPicture" column="product_picture"></result>
        <result property="productPrice" column="product_price"></result>
        <result property="productSellingPrice" column="product_selling_price"></result>
    </resultMap>
    <select id="selectShoppingCartByIds" resultMap="shoppingCartProduct">
        select
            s.shopping_cart_id,
            s.num,
            s.product_id,
            p.product_name,
            p.product_title,
            p.product_intro,
            p.product_picture,
            p.product_price,
            p.product_selling_price
            FROM
            shopping_cart AS s
            left JOIN
            product AS p
            ON s.product_id = p.product_id
            WHERE
            s.shopping_cart_id 
            in (<foreach collection="list" index="id" separator=",">
                #{id}
            </foreach>)
    </select>

尝试解决问题的过程

1.事务问题

  • 一开始,我以为是事务问题,于是在service层加上了@Transactional开启事务
@Override
@Transactional
public GetData postOrders(List<Long> shoppingCartIds, Long userId) {
    //1.判断用户是否存在
    if (msUserMapper.FindUser(userId) == null) {
        GetData getData=new GetData(500,"无此账号",null);
        return getData;
    }
    //2.生成订单
    Orders orders=new Orders();
    orders.setOrderNum(UUID.randomUUID().toString());
    orders.setUserId(userId);
    orders.setOrderTime(new Date());
    orderProductMapper.addOrders(orders);
    System.out.println(orders.getOrderId());
    System.out.println(orders.getOrderId().getClass().getTypeName());
    System.out.println(shoppingCartIds);

    //3.查询购物车商品数据
    List<ShoppingCartProductVo> shoppingCartProductVos = productMapper.selectShoppingCartByIds(shoppingCartIds);
    System.out.println(shoppingCartProductVos.size());
    System.out.println(shoppingCartProductVos);
    List<OrdersDtl> ordersDtls = new ArrayList<>();
    for (ShoppingCartProductVo vo : shoppingCartProductVos) {
        OrdersDtl ordersDtl = new OrdersDtl();
        ordersDtl.setOrderId(orders.getOrderId());
        ordersDtl.setProductId(vo.getProductId());
        ordersDtl.setProductIntro(vo.getProductIntro());
        ordersDtl.setProductName(vo.getProductName());
        ordersDtl.setProductPicture(vo.getProductPicture());
        ordersDtl.setProductPrice(vo.getProductPrice());
        ordersDtl.setProductSellingPrice(vo.getProductSellingPrice());
        ordersDtl.setProductTitle(vo.getProductTitle());
        ordersDtl.setNum(vo.getNum());
        ordersDtls.add(ordersDtl);
    }
    System.out.println(ordersDtls);
    orderProductMapper.addBatchOrderDtlsInt(ordersDtls);
    System.out.println(1);
    int rs =shoppingCartMapper.deleteShoppingCarts(shoppingCartIds);

    if (rs>0){
        GetData getData=new GetData(200,"操作成功",null);
        return getData;
    }else {
        GetData getData=new GetData(500,"操作成功",rs);
        return getData;
    }

}
  • 现在想想,真是没抓住重点,看错了代码的报错信息

2.MyBatis一级缓存问题

  • 接着排查发现发现查询出的数据与同样的代码在数据库里不一样,人当场傻了
  • 面向百度编程后认为是出现了MyBatis一级缓存问题
  • 于是在yml文件中关闭关闭了MyBatis一级缓存
# 配置mybatis
mybatis:
  # mapper配置文件
  mapper-locations: classpath:mapper/*.xml
  # resultType别名,没有这个配置resultType包名要写全,配置后只要写类名
  type-aliases-package: com.example.demo.com.mashang.dao
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
    local-cache-scope: statement # 设置一级缓存关闭,mybatis默认开启
  • 当然还是不对,无可奈何之下,我只能回归最初的报错信息,意思大概是文件映射有问题

问题的产生及其原因

  • 没办法,如果真是映射出了错,那就只能一个一个排查过去了
  • 终于在结合了springboot的报错日志
  • log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
select 
s.num, s.product_id, p.product_name, p.product_title, p.product_intro, p.product_picture, p.product_price, p.product_selling_price 
FROM shopping_cart AS s 
INNER JOIN product AS p 
ON s.product_id = p.product_id 
WHERE s.shopping_cart_id 
in ( ? , ? , ? )
  • 终于,我发现mybatis执行的语句中,三个问号插入的值是固定的0,1,2
  • 也就是循环插入出了问题
  • 果然,我错误的使用了标签index

解决方式

  • 只要认真检查mybatis的映射文件,我的话是把标签换成即可,以下是修改后的mybatis映射文件
<resultMap id="shoppingCartProduct" type="shoppingCartProductVo">
    <id property="shoppingCartId" column="shopping_cart_id"></id>
    <result property="productId" column="product_id"></result>
    <result property="num" column="num"></result>
    <result property="productName" column="product_name"></result>
    <result property="productTitle" column="product_title"></result>
    <result property="productIntro" column="product_intro"></result>
    <result property="productPicture" column="product_picture"></result>
    <result property="productPrice" column="product_price"></result>
    <result property="productSellingPrice" column="product_selling_price"></result>
</resultMap>
<select id="selectShoppingCartByIds" resultMap="shoppingCartProduct">
    select
        s.shopping_cart_id,
        s.num,
        s.product_id,
        p.product_name,
        p.product_title,
        p.product_intro,
        p.product_picture,
        p.product_price,
        p.product_selling_price
        FROM
        shopping_cart AS s
        left JOIN
        product AS p
        ON s.product_id = p.product_id
        WHERE
        s.shopping_cart_id 
        in (<foreach collection="list" item="id" separator=",">
            #{id}
        </foreach>)
</select>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java HashMap底层实现原理

    Java HashMap底层实现原理

    HashMap在不同的JDK版本下的实现是不同的,在JDK1.7时,HashMap 底层是通过数组+链表实现的;而在JDK1.8时,HashMap底层是通过数组+链表或红黑树实现的,本详细介绍了HashMap底层是如何实现的,需要的朋友可以参考下
    2023-05-05
  • mybatis中注解与xml配置的对应关系和对比分析

    mybatis中注解与xml配置的对应关系和对比分析

    这篇文章主要介绍了mybatis中注解与xml配置的对应关系和对比分析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • java安全编码指南之:Mutability可变性详解

    java安全编码指南之:Mutability可变性详解

    这篇文章主要介绍了java安全编码指南之:Mutability可变性详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 一文读懂Java多线程背后的故事

    一文读懂Java多线程背后的故事

    Java是一种广泛使用的编程语言,而多线程是Java程序员必不可少的一部分,Java的多线程支持具有确保数据同步、最大化利用CPU资源、并行处理任务等众多优点,本文从实际应用场景出发,为您详细介绍 Java 多线程的各个方面的实际应用及背景
    2023-06-06
  • 一文教你搞懂SpringBoot自定义拦截器的思路

    一文教你搞懂SpringBoot自定义拦截器的思路

    在开发中,都离不开拦截器的使用,比如说在开发登录功能时,实现权限管理功能时等,这篇文章主要带大家使用SpringBoot梳理自定义拦截器的思路,需要的可以参考一下
    2023-08-08
  • Java中Comparable与Comparator的区别解析

    Java中Comparable与Comparator的区别解析

    这篇文章主要介绍了Java中Comparable与Comparator的区别解析,实现Comparable接口,重写compareTo方法,一般在实体类定义的时候就可以选择实现该接口,提供一个默认的排序方式,供Arrays.sort和Collections.sort使用,需要的朋友可以参考下
    2024-01-01
  • MyBatis-Plus执行SQL分析打印过程

    MyBatis-Plus执行SQL分析打印过程

    这篇文章主要介绍了MyBatis-Plus执行SQL分析打印过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • 使用mybatisPlus生成oracle自增序列遇到的坑及解决

    使用mybatisPlus生成oracle自增序列遇到的坑及解决

    这篇文章主要介绍了使用mybatisPlus生成oracle自增序列遇到的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • SpringBoot+Mybatis项目使用Redis做Mybatis的二级缓存的方法

    SpringBoot+Mybatis项目使用Redis做Mybatis的二级缓存的方法

    本篇文章主要介绍了SpringBoot+Mybatis项目使用Redis做Mybatis的二级缓存的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • 你的Idea还有BUG吗不妨试试另一个开发神器

    你的Idea还有BUG吗不妨试试另一个开发神器

    Spring Tool Suite(STS)就是一个基于Eclipse的开发环境, 用于开发Spring应用程序。本文给大家给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-12-12

最新评论