mybatis plus相同Id与xml配置错误时,mybatis plus解决逻辑

前言

处理做项目的问题,其中不乏奇奇怪怪的问题,其中mybatis plus的问题感觉有点隐蔽,有些是运行时出现,有些是运行到具体的逻辑触发,对于应用的状态监控提出了极大的挑战,应用的状态由健康检查接口提供,或者TCP或者HTTP,那么健康检查要怎么写呢,比如K8S,一般使用HTTP GET方式要定时监控POD状态。

准备

准备SpringBoot与mybatis的demo,这个参考SpringBoot官网即可,数据库使用MySQL docker部署,毕竟docker部署方便:Basic Steps for MySQL Server Deployment with Docker

docker run --name mysql_8.0 -e MYSQL_ROOT_PASSWORD=123456i -d -i -p 3306:3306  container-registry.oracle.com/mysql/community-server:8.0

就可以使用client连接上去,然后建库表和demo数据,需要修改非本地登录mysql的能力

更新root登录限制开放

确认OK

造数据

mybatis plus的Id相同

依赖如下

    <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.0.RELEASE</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.3</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.6</version></dependency></dependencies>

dao与配置、main类

@SpringBootApplication
@MapperScan(basePackages = "com.feng.boot.mybatis.demo.dao")
public class MybatisMain {public static void main(String[] args) {SpringApplication.run(MybatisMain.class, args);}
}@Mapper
public interface DemoDao {@Select("select * from user")List<User> selectUser();@Select("select * from user where name = #{name}")List<User> selectUser(String name);}@RestController
public class DemoController {@Lazy@Autowiredprivate DemoDao demoDao;@RequestMapping("/user")public List<User> listUser(String name){return demoDao.selectUser(name);}

SpringBoot数据源配置自行处理,启动后日志

 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ /               |         3.3.2 
2024-01-09 21:27:34.043 ERROR 3340 --- [           main] c.b.m.core.MybatisConfiguration          : mapper[com.feng.boot.mybatis.demo.dao.DemoDao.selectUser] is ignored, because it exists, maybe from xml file

但是 启动不会保错,如果是mybatis的starter则启动直接保错

让我们访问http://localhost:8080/user?name=demo

理论上只会有一条结果,然而:

 

2条,什么原因呢,开启trace日志

为啥不是我方法的执行结果,SQL都不对,这其实是mybatis plus留下的坑

 源码分析

启动过程就埋了坑,在

com.baomidou.mybatisplus.core.MybatisMapperAnnotationBuilder

通过generateResultMapName生成mybatis的Id时,mybatis plus做了定制

    private String generateResultMapName(Method method) {Results results = method.getAnnotation(Results.class);if (results != null && !results.id().isEmpty()) {return type.getName() + "." + results.id();}StringBuilder suffix = new StringBuilder();//参数拼接for (Class<?> c : method.getParameterTypes()) {suffix.append("-");suffix.append(c.getSimpleName());}//如果没有参数,使用-voidif (suffix.length() < 1) {suffix.append("-void");}//类名+方法名+参数类型拼接return type.getName() + "." + method.getName() + suffix;}

所以对于mybatis plus,对于方法重载不存在id冲突的可能性,在

com.baomidou.mybatisplus.core.MybatisConfiguration

 所以出现启动时的error日志,然后直接return了,所以下面的第2条是没有载入mappedstatement

所以SQL永远是第1条,无论我们怎么调用

mybatis-starter

原生的mybatis-starter的org.apache.ibatis.builder.annotation.MapperAnnotationBuilder

实际上id也差不多,也是通过-void方式实现无参数id

 

但是在org.apache.ibatis.builder.MapperBuilderAssistant

会使用不带参数的Id来做校验,在org.apache.ibatis.session.Configuration

而不是像mybatis plus那样直接return了。

解决方法

无非是id冲突,只要安装方法名唯一的情况即可,不使用方法重载

结果OK

mybatis的xml配置错误的情况

如果使用xml配置,那么也会存在出现错误的情况

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.feng.boot.mybatis.demo.dao.DemoDao"><!--<select id="selectUser" parameterType="java.lang.String" resultType="com.feng.boot.mybatis.demo.entity.User">select * from user where name = #{name}</select>--><select id="selectUser" parameterType="java.lang.String" resultMap="com.feng.boot.mybatis.demo.entity.User">select * from user where name = #{name}</select><select id="selectUsers" resultType="com.feng.boot.mybatis.demo.entity.User">select * from user</select></mapper>

笔者故意写错selectUser的xml,但是笔者在调用

    @RequestMapping("/users")public List<User> listUser(){return demoDao.selectUsers();}

跟第1个xml毫无关系,但是调用报错

java.lang.IllegalArgumentException: Result Maps collection does not contain value for com.feng.boot.mybatis.demo.entity.Userat org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:1031) ~[mybatis-3.5.6.jar:3.5.6]

 其实这个都还好,关键是启动毫无错误,然而执行任意一条正确的SQL却报错了,莫非mybatis绝得还可以抢救一下。而且错误信息可以跟正确执行的逻辑毫无相关,如果启动后仅仅看启动日志,就会埋下极大隐患,需要健康检查覆盖mybatis才行。

源码分析

在mybatis的源码中,org.apache.ibatis.session.Configuration

mybatis的设计是,在任意statement执行前,执行未完成态的statement,执行快速失败,既然知道未完成,为什么启动不报错,也不任何日志提示呢

 根源来自org.apache.ibatis.builder.xml.XMLMapperBuilder

 xml解析失败,并不是报错,也没有日志,直接放在了未完成的statement,这里好歹给个日志啊,估计mybatis是准备支持抢救一下,不对,是支持statement在运行态注入一些数据实现完成态。

总结

mybatis plus这个是直接丢弃相同Id的statement,安装先后顺序,会造成执行过程的误解,不过有日志可以查看,而且mybatis原生的starter是有校验的,直接报错了。mybatis的xml如果写错,那么启动居然不报错,执行任意statement前需要执行未完成的statement,来达到快速失败的情况,这种情况对健康检查提出了新挑战,否则可能出现启动OK,但是mybatis失败的情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/609023.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【基础工具篇使用】Windows环境下瑞芯微开发工具的安装和使用

文章目录 Rockchip 烧录驱动的安装Rockchip 烧录工具使用导入配置MASKROM 模式烧录LOADER 模式烧录Update.img 包的烧录 Rockchip 烧录驱动的安装 瑞芯微提供了 RKDevTool 上位机烧录工具&#xff0c;此工具只能在 Windows 系统下运行&#xff0c;运行前要先安装驱动文件 Ro…

mitmproxy代理抓包使用mock数据

第一步 安装Python环境 下载Python环境安装包https://www.python.org/getit/https://link.jianshu.com/?thttps%3A%2F%2Fwww.python.org%2Fgetit%2F &#xff08;图a&#xff09; 安装Python的时候勾选“Add Python 3.5 to PATH”选项&#xff08;图a&#xff09; 打开CMD命…

Pytest接口自动化测试框架搭建

一. 背景 Pytest目前已经成为Python系自动化测试必学必备的一个框架&#xff0c;网上也有很多的文章讲述相关的知识。最近自己也抽时间梳理了一份pytest接口自动化测试框架&#xff0c;因此准备写文章记录一下&#xff0c;做到尽量简单通俗易懂&#xff0c;当然前提是基本的py…

书生·浦语大模型实战营第二次课堂笔记

文章目录 什么是大模型&#xff1f;pip&#xff0c;conda换源模型下载 什么是大模型&#xff1f; 人工智能领域中参数数量巨大、拥有庞大计算能力和参数规模的模型 特点及应用&#xff1a; 利用大量数据进行训练拥有数十亿甚至数千亿个参数模型在各种任务重展现出惊人的性能 …

数据结构入门到入土——链表(完)LinkedList

目录 一&#xff0c;双向链表 1.单向链表的缺点 2.什么是双向链表&#xff1f; 3.自主实现双向链表 接口实现&#xff1a; 二&#xff0c;LinkedList 1.LinkedList的使用 1.1 什么是LinkedList&#xff1f; 1.2 LinkedList的使用 1.LinkedList的构造 2.LinkedList的…

Pruning Papers

[ICML 2020] Rigging the Lottery: Making All Tickets Winners 整个训练过程中mask是动态的&#xff0c;有drop和grow两步&#xff0c;drop是根据权重绝对值的大小丢弃&#xff0c;grow是根据剩下激活的权重中梯度绝对值生长没有先prune再finetune/retrain的两阶段过程 Laye…

工业异常检测AnomalyGPT-Demo试跑

写在前面&#xff1a;如果你有大的cpu和gpu可以使用&#xff0c;直接根据官方的安装说明就可以&#xff0c;如果没有&#xff0c;可以点进来试着看一下我个人的安装经验。 一、试跑环境 NVIDIA4090显卡24g,cpu内存33G&#xff0c;交换空间8g,操作系统ubuntu22.04(试跑过程cpu…

SEO写作:撰写在Google上排名的博客文章的13个技巧

随着排名的提高&#xff0c;您的网站可以提高其整体知名度。最终目标是通过有效的优化来推动自然流量&#xff0c;增加转化率&#xff0c;并实现业务目标。 如果你不针对搜索引擎优化你的内容&#xff0c;你的网站可能会在搜索引擎结果页面&#xff08;SERP&#xff09;上出现…

第7章-第9节-Java中的Stream流(链式调用)

1、什么是Stream流 Lambda表达式&#xff0c;基于Lambda所带来的函数式编程&#xff0c;又引入了一个全新的Stream概念&#xff0c;用于解决集合类库既有的鼻端。 2、案例 假设现在有一个需求&#xff0c; 将list集合中姓张的元素过滤到一个新的集合中&#xff1b;然后将过滤…

详解Oracle数据库的启动

Oracle数据库的启动&#xff0c;其概念可参考Overview of Instance and Database Startup。 其过程可参见下图&#xff1a; 当数据库从关闭状态进入打开数据库状态时&#xff0c;它会经历以下阶段。 阶段Mount状态描述1实例在没有挂载数据库的情况下启动实例已启动&#xff…

SpringBoot 注解超全详解

使用注解的优势&#xff1a; 采用纯java代码&#xff0c;不在需要配置繁杂的xml文件 在配置中也可享受面向对象带来的好处 类型安全对重构可以提供良好的支持 减少复杂配置文件的同时亦能享受到springIoC容器提供的功能 1 注解详解&#xff08;配备了完善的释义&#xff0…

深入了解鸿鹄工程项目管理系统源码:功能清单与项目模块的深度解析

工程项目管理软件是现代项目管理中不可或缺的工具&#xff0c;它能够帮助项目团队更高效地组织和协调工作。本文将介绍一款功能强大的工程项目管理软件&#xff0c;该软件采用先进的Vue、Uniapp、Layui等技术框架&#xff0c;涵盖了项目策划决策、规划设计、施工建设到竣工交付…

5分钟彻底搞懂什么是token

大家好啊&#xff0c;我是董董灿。 几年前在一次工作中&#xff0c;第一次接触到自然语言处理模型 BERT。 当时在评估这个模型的性能时&#xff0c;领导说这个模型的性能需要达到了 200 token 每秒&#xff0c;虽然知道这是一个性能指标&#xff0c;但是对 token 这个概念却不…

新年喝酒有讲究,怎么喝葡萄酒呢?

中国的新年有着独特又深远的意义&#xff0c;无论人在天涯海角&#xff0c;回家团圆是每个人的心愿。新年亲朋好友欢聚一堂&#xff0c;没有酒哪有气氛&#xff0c;所以喝酒是必不可少的活动项目。云仓酒庄的品牌雷盛红酒LEESON分享那么&#xff0c;新年喝啥酒&#xff0c;葡萄…

uniapp 创建组件

组件&#xff1a;用于将某个功能的 HTML、CSS、JS 封装到一个文件中&#xff0c;提高代码的复用性和可维护性。 创建组件 一、在根目录中创建 components 文件夹&#xff0c;右键点击新建组件。 二、输入组件名称、选择默认模板、点击创建组件。 三、在组件中正常编写内容即可…

什么是MOM,与MES系统的差异是什么

MOM基本概念介绍 由于绝大多数MES只关注生产执行的核心作用, 对维护管理、质量管理和库存管理的重视程度有限,有时甚至缺少这部分功能, 并且未提高到与生产运营相类似的复杂程度, 难以充分满足现代制造企业对其制造运营区域的业务管理需求, 进而直接影响对企业的运营管理效果。…

C/C++学习笔记 vcpkg使用备忘及简要说明

一、简述 vcpkg 是一个免费的 C/C 包管理器&#xff0c;用于获取和管理库。从 1500 多个开源库中进行选择&#xff0c;一步下载并构建&#xff0c;或者添加您自己的私有库以简化构建过程。由 Microsoft C 团队和开源贡献者维护。 官方教程 vcpkg 文档 | Microsoft Learnvcpkg …

数据结构与算法(十)深度优先搜索与广度优先搜索

广度优先搜索 广度优先搜索&#xff1a;从一个顶点出发&#xff08;由开始时顶点创造顺序优先决定&#xff09;&#xff0c;访问所有没有被访问过的临节点。然后在从被访问过的节点出发&#xff0c;重复之前的操作 如下为一个图 从1出发&#xff0c;先后访问2 3&#xff0c;之后…

横版长图一键切割,短图制作高效又便捷!

在数字时代&#xff0c;图片处理已经成为了我们日常工作和生活中不可或缺的一部分。为了满足大家对于高效、便捷的图片处理需求&#xff0c;我们推出了一款全新的图片处理工具——横版长图一键切割&#xff01; 首先&#xff0c;我们进入首助编辑高手主页面&#xff0c;会看到…

优化改进YOLOv8算法之AKConv(可改变核卷积),即插即用的卷积,效果秒杀DSConv

目录 1 AKConv原理 1.1 Define the initial sampling position 1.2 Alterable convolutional operation 1.3 Extended AKConv 2 YOLOv8中加入AKConv模块 2.1 AKConv.py文件配置 2.2 task.py配置 2.3 创建添加优化点模块的yolov8-AKConv.yaml 2.4 训练 1 AKConv原理 …