【mybatis plus源码解析】(一)mybatis plus执行原理,mybatis plus是如何实现自动注入CRUD操作_mybatisplus源码解析-程序员宅基地

技术标签: java  mybatis plus  mybatis  orm  源码  

系列文章目录

【mybatis plus源码解析】(一)mybatis plus执行原理,mybatis plus是如何实现自动注入CRUD操作
【mybatis plus源码解析】(二)详解SQL注入器底层原理,mybatis plus是如何实现自动注入CRUD操作


前言

前面文章讲过mybatis相关源码理解,感兴趣的可以看看我之前的文章。这回顺道看看mybatis plus的源码

一、mybatis plus是什么?

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
特性
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
支持的数据库
任何能使用 MyBatis 进行 CRUD, 并且支持标准 SQL 的数据库,具体支持情况如下,如果不在下列表查看分页部分教程 PR 您的支持。

MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb

达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库

二、搭建测试环境,运行代码看流程

在这里插入图片描述
这里用经典的一套执行流程
打断点到这一步
在这里插入图片描述
发现配置类中mappedStatements对象已经放入执行相关方法sql映射语句。这里其实能猜出个大概,其实就是在初始化配置的时候mybatis plus已经为我们封装好了默认方法sql映射语句。这也就是为什么只要继承BaseMapper接口我们就能使用selectMaps,selectById等等相关的方法。

三,来看看mybatisXMLConfigBuilder.parse()方法都做了啥

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到这一步停下来,发现调用了configuration.addMapper(boundType);方法。这个configuration是mybatis plus继承mybatis原有的Configuration类的新类MybatisConfiguration。所以我们进入mybatisConfigurationaddMapper(boundType)方法看看
在这里插入图片描述
又调用MybatisMapperRegistry的addMapper方法,继续进入看看

    @Override
    public <T> void addMapper(Class<T> type) {
    
        if (type.isInterface()) {
    
            if (hasMapper(type)) {
    
                // TODO 如果之前注入 直接返回
                return;
                // TODO 这里就不抛异常了
//                throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
            }
            boolean loadCompleted = false;
            try {
    
                // TODO 这里也换成 MybatisMapperProxyFactory 而不是 MapperProxyFactory
                knownMappers.put(type, new MybatisMapperProxyFactory<>(type));
                // It's important that the type is added before the parser is run
                // otherwise the binding may automatically be attempted by the
                // mapper parser. If the type is already known, it won't try.
                // TODO 这里也换成 MybatisMapperAnnotationBuilder 而不是 MapperAnnotationBuilder
                MybatisMapperAnnotationBuilder parser = new MybatisMapperAnnotationBuilder(config, type);
                parser.parse();
                loadCompleted = true;
            } finally {
    
                if (!loadCompleted) {
    
                    knownMappers.remove(type);
                }
            }
        }
    }

发现创建了MybatisMapperAnnotationBuilder建造者并解析
来看看MybatisMapperAnnotationBuilder的parse()方法

    @Override
    public void parse() {
    
        String resource = type.toString();
        if (!configuration.isResourceLoaded(resource)) {
    
            loadXmlResource();
            configuration.addLoadedResource(resource);
            String mapperName = type.getName();
            assistant.setCurrentNamespace(mapperName);
            parseCache();
            parseCacheRef();
            InterceptorIgnoreHelper.InterceptorIgnoreCache cache = InterceptorIgnoreHelper.initSqlParserInfoCache(type);
            for (Method method : type.getMethods()) {
    
                if (!canHaveStatement(method)) {
    
                    continue;
                }
                if (getAnnotationWrapper(method, false, Select.class, SelectProvider.class).isPresent()
                    && method.getAnnotation(ResultMap.class) == null) {
    
                    parseResultMap(method);
                }
                try {
    
                    // TODO 加入 注解过滤缓存
                    InterceptorIgnoreHelper.initSqlParserInfoCache(cache, mapperName, method);
                    parseStatement(method);
                } catch (IncompleteElementException e) {
    
                    // TODO 使用 MybatisMethodResolver 而不是 MethodResolver
                    configuration.addIncompleteMethod(new MybatisMethodResolver(this, method));
                }
            }
            // TODO 注入 CURD 动态 SQL , 放在在最后, because 可能会有人会用注解重写sql
            try {
    
                // https://github.com/baomidou/mybatis-plus/issues/3038
                if (GlobalConfigUtils.isSupperMapperChildren(configuration, type)) {
    
                    parserInjector();
                }
            } catch (IncompleteElementException e) {
    
                configuration.addIncompleteMethod(new InjectorResolver(this));
            }
        }
        parsePendingMethods();
    }

在这里插入图片描述
这里就加入mybatisplus自己的动态sql
执行完这个语句后配置当中已经有相关动态语句。

关于mybatis动态注入相关类的uml图

在这里插入图片描述
ISqlInjector顶级接口
DefaultSqlInjectorSQL 默认注入器
在这里插入图片描述篇幅原因后续关于动态sql这块留到下篇文章讲解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_35270805/article/details/123825416

智能推荐

计算复杂性理论初步(一)多项式时间归约_多项式归约-程序员宅基地

文章浏览阅读2.5k次,点赞2次,收藏12次。一、归约的意义求解一个算法问题的时候,我们往往可以直观地感受到有些问题是比较难的,有些问题是比较简单的,但是我们并不能因为没有设计出一个比较高效的算法,就说它是一个难问题,所以问题的难易是相对的,我们需要一个科学的手段来界定问题的难易我们可以用问题之间的归约,来界定两个问题之间相对难易程度的基本手段二、优化问题与判定问题很多经典的难问题都是优化问题,而一个优化问题往往可以..._多项式归约

Memory access ordering part 3 - memory access ordering in the ARM Architecture_accesses are inner-shareable-程序员宅基地

文章浏览阅读1.5k次。Memory access ordering part 3 - memory access ordering in the ARM ArchitecturePosted by leiflindholm in ARM Processors on Oct 19, 2011 6:36:00 PM In my previous posts, I have introduced th_accesses are inner-shareable

Node.js:download下载文件_nodejs download-程序员宅基地

文章浏览阅读4k次。文档npm: https://www.npmjs.com/package/downloadgithub: https://github.com/kevva/download安装npm i download定义方法Promise download(url, destination?, options?)url: string 文件地址destination: string 文件保存目录,如果设置了该参数,就会自动保存options: _nodejs download

fastapi 大型应用_FastAPI(高性能Web框架) V0.60.1 官方版-程序员宅基地

文章浏览阅读728次。FastAPI是一个快速高性能的Web框架,用于基于标准python类型提示使用Python 3.6+构建API。拥有看齐NodeJS的性能,可以采用了FastAPI库来生成一个REST服务器,可以查询该服务器以获得预测。【功能特色】快速编码:将功能开发速度提高约200%至300%。错误少:减少约40%的人为错误(开发人员)。直观:强大的编辑器支持。完成无处不在。调试时间更少。简易:旨在易于使用和..._采用 fastapi 库生成一个 rest 服务器,可以通过查询获得预测结果

VMWare安装&配置Win7详解_虚拟机win7sp1补丁下载-程序员宅基地

文章浏览阅读2.3w次,点赞57次,收藏155次。VMWare使用Win7安装及配置详解随着Win11的发布,巨硬向我们展示如何将Windows改装成为MacOS和Linux的风格(误)。相信还是有很多小伙伴对于上一代Windows的操作系统十分怀念的,那么本文就带领大家通过VMWare虚拟机的方式来进行Win7的日常使用和体验..._虚拟机win7sp1补丁下载

iOS开发XCODE5 SVN配置 使用办法 (转) 收藏一下-程序员宅基地

文章浏览阅读67次。标签:xcode5svnxcodesvn使用xcode自带的svnxcodesvn版本操作xcode自带svn版本这两天响应老板要求,把所有代码放到公司的SVN服务器上,按照我的想法肯定是就苹果组建一个服务器,然后内部版本控制,自带的Xcode就有这个功能,之前也这么做过,但是xcode4.X系列S..._(mf) mine-full, (tf) theirs-full

随便推点

PKM工具的作用-程序员宅基地

文章浏览阅读203次。1.帮助你养成习惯2.将一些机械性可程序化的部分交由它来完成:如自动备份、文件命名、文件存放等3.方便的对内容对内容进行修改,不能修改的网页的价值很低。因为你有你的参点还及你的经验,需要和它综合;你需要对行内容删减、标记,甚至写下自己的心得;便于再次的复习或将来找到它4.你需要对多个相关内容进行合并、关联,让自己的下次更方便更省时地找到它,同时,这样做,可能会触发..._pkm11com

程序员常用资源工具集合(建议收藏)_程序员记录文档资源包-程序员宅基地

文章浏览阅读318次。搜索资源网站学习技术过程我们经常需要使用搜索引擎来检索资料,国内常用的也就是某度了。当然有条件的话,搜索引擎首先还是推荐使用 Google,如果没办法使用,可以使用以下几个作为备用:BingBing 国际版:https://cn.bing.com/比某度好用,之前还被停用了几天,最近可以了。DuckDuckGoDuckDuckGo:https://duckduckgo...._程序员记录文档资源包

ubuntu18.04安装matlab2018a-程序员宅基地

文章浏览阅读1.9k次,点赞6次,收藏27次。一、首先下载百度网盘链接:https://pan.baidu.com/s/1M6KafnsljmYV9_5m_1pXMw提取玛:jp76二、解压并且安装1、挂载第一个镜像文件iso1执行以下命令:cd ~mkdir matlabsudo mount -t auto -o loop /home/bing/lu/matlab2018a/R2018a_glnxa64_dvd1.iso /home/bing/matlab2、安装第一个映像文件执行以下命令:sudo ./matlab/ins_ubuntu18.04安装matlab2018a

鲜花静态HTML网页作业作品 大学生鲜花网页设计制作成品 简单DIV CSS布局网站_html页面动态花束图配文字-程序员宅基地

文章浏览阅读280次。 鲜花网页设计 、鲜花商城网页制作、在线花店网站、盆栽网、花卉网等网站的设计与制作。️HTML鲜花网页设计,采用DIV+CSS布局,共有多个页面,排版整洁,内容丰富,主题鲜明,首页使用CSS排版比较丰富,色彩鲜明有活力。顶部导航及底部区域背景色为100%宽度,主体内容区域宽度 一套优质的网页设计应该包含 (具体可根据个人要求而定)网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程序方面:计划采用最新的网页编程语言HTML5+CS_html页面动态花束图配文字

spring常见面试题_spring注解面试题-程序员宅基地

文章浏览阅读383次。spring常见面试题1.spring中的拦截器和过滤器介绍2.说一下spring中的IOC3.spring中的异常处理4.jdk动态代理和cglib代理5.spring bean的生命周期6.spring IOC原理7.BeanFactory和FactoryBean的区别8.spring解决循环依赖9.spring默认为单例模式为什么10.AspectJ和spring aop代理区别11.spring的bean是线程安全的么12.spring的优点13.spring中的设计模式_spring注解面试题

c++十大排序——堆排序_c++堆排序-程序员宅基地

文章浏览阅读8.5k次,点赞19次,收藏109次。1、堆排序堆排序采用堆的这种数据结构,堆首先是一颗完全二叉树。堆又分为大顶堆和小顶堆大顶堆就是父节点数值大于等于左右节点数值小顶堆是父节点数值小于等于左右节点数值下标为i的节点的父节点下表为:(i-1)/2下标为i的节点的左孩子下表为:i*2+1下标为i的节点的右孩子下表为:i*2-1#include<iostream>using namespace std;void sw(int &a,int &b) { int temp _c++堆排序

推荐文章

热门文章

相关标签