返回顶部
首页 > 资讯 > 后端开发 > Python >Mybatis-Plus的应用场景描述及注入SQL原理分析
  • 851
分享到

Mybatis-Plus的应用场景描述及注入SQL原理分析

2024-04-02 19:04:59 851人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录一、背景1.1 传统mybatis的弊端1.2 MyBatis-Plus的定位1.3 特性1.4 原理解析二、准备工作2.1 基础接口BaseMapper2.2 创建实体类对象2

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。

特性:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

支持数据库:

  • mysql 、 mariadb 、 oracle 、 db2 、 h2 、 hsql 、 sqlite 、 postgresql 、 sqlserver 、 presto
  • 达梦数据库 、 虚谷数据库 、 人大金仓数据库

一、背景

1.1 传统Mybatis的弊端

1.1.1 场景描述

假设有两张表:一张商品表、一张订单表,具体表的字段如下:

现有如下需求:

  • 分别根据id查询商品表和订单表所有信息
  • 根据支付状态和通知状态查询订单表信息
  • 对订单表增加一个订单状态,根据订单状态查询订单信息

1.1.2 需求

需求a:根据id查询商品表:


@Select(" SELECT p.id ,p.name ,p.picture ,p.type ,p.price, p.type, p.time
          FROM product p  where id = #{id} ")
List<Product> getProductsBYId(@Param("id") Integer id);

根据id查询订单表所有信息:


@Select(" SELECT o.id ,o.pay_no ,o.user_id ,o.product_id ,o.pay_price, o.num, o.pay_time, o.order_type, o.notif_type
          FROM order o  where id = #{id} ")
List<Order> getOrderBYId(@Param("id") Integer id);

需求b:根据支付状态和通知状态查询订单表信息


​@Select(" SELECT o.id ,o.pay_no ,o.user_id ,o.product_id ,o.pay_price, o.num, o.pay_time, o.order_type, o.notif_type
          FROM order o  where order_type= #{orderType} ")
List<Order> getOrderBYId(@Param("orderType") Integer orderType);
 
@Select(" SELECT o.id ,o.pay_no ,o.user_id ,o.product_id ,o.pay_price, o.num, o.pay_time, o.order_type, o.notif_type
          FROM order o  where notify_type= #{notifyType} ")
List<Order> getOrderBYId(@Param("notifyType") Integer notifyType);

需求c:对订单表增加一个订单状态status,根据订单状态查询订单信息。

传统mybaits需要三步:首先需要在订单表里加个字段,然后在订单的实体类添加这个属性,并且将所有dao层设计该状态的的查询sql都修改一遍,加上这个字段。

1.1.3 上述方式有什么问题呢?

需求a:对于不同的实体类,即使查询的目的一致,仍然需要重复构造类似的sql语句,仅仅是表字段和表信息不同。

需求b:对于相似的查询条件,针对某个单一场景必须构造不同的sql,造成sql语句的大量冗余。

需求c:将dao层所有涉及到新增字段的sql都需要修改一遍,这个过程比较繁琐且容易出错。

使用mybatis-plus就可以解决上述问题。

1.1.4 Myatis-plus的解决方案

首先让ProductMapper和OrderMapper继承BaseMapper类:


public interface ProductMapper extends BaseMapper<Product> {
}
 
public interface OrderMapper extends BaseMapper<Order> {
  
}

需求a:

分别根据id查询商品表和订单表:由于BaseMapper中提供了selectById的方法,可以直接根据具体业务场景,传入指定的参数例如(id=1)即可。无需书写具体的sql语句,至于sql自动生成的原理将在下面介绍;


productMapper.selectById(1);
orderMapper.selectById(1);

需求b:

此时利用BaseMapper.selectList(Wapper queryWrapper)方法直接构造查询条件,例如查询支付状态为2和通知状态为1的订单信息


orderMapper.selectList(new QueryWrapper<Order>().eq("orderType",2));
orderMapper.selectList(new QueryWrapper<Order>().eq("notifyType",1));
orderMapper.selectList(new QueryWrapper<Order>().eq("orderType",2));orderMapper.selectList(new QueryWrapper<Order>().eq("notifyType",1));

此时我们可以发现:使用了Mybatis-plus以后,我们更加聚焦于业务本身,对于上述相似的应用场景,无需构造雷同的SQL,利用包装器直接传入查询条件。

需求c:

前两步与传统mybatis一致,由于MyBatis-plus无需手动创建SQL,因此减少了大量的重复劳动。

1.2 MyBatis-Plus的定位

MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

1.3 特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑;
  • 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作。

1.4 原理解析

本文针对MyBatis-plus中的核心功能:SQL自动注入功能,进行流程分析及原理探究。

二、准备工作

先从一个简单的demo入手,感受一下MyBatis-plus的便捷性。

2.1 基础接口BaseMapper

源码中提供了一个基础接口,里面包含了基本的增删改查方法。

2.2 创建实体类对象

2.3 业务接口UserMapper

业务中根据具体实体对象,继承该抽象接口。

2.4 测试用例

控制台显示:MyBatis-plus最终为我们自动生成了SQL语句。根据上述操作分析:UserMapper继承了BaseMapper,拥有了deleteById的方法,但是MyBatis-plus是基于mybatis的增强版,关键在于最终仍然需要提供具体的SQL语句,来进行数据库操作。

下面就通过debug由上而下分析mybatis-plus是如何生成业务sql以及自动注入的。

三、SQL语句存储在哪里?

mappedStatements:描述sql信息

如下图所示:mybatis为我们生成了一个代理对象,里面包含了一些重要的属性。

具体如下:

userMapper——>mybatisMapperProxy——>sqlSession——>sqlSessionFactory——>configuration——>mappedStatements——>mappedStatement——>sql语句

至此我们可以发现每一个SQL语句对应一个mappedStatement,mappedstatements存储在configuration文件(configuration是mybatis的全局配置文件,包含数据源、mapper、其他配置信息)中。

四、SQL语句是什么时候注入的?

4.1 AbstractMethod.addMappedStatement

基于上面的分析,想要知道SQL语句什么时候拿到的,就是要找到mappedStatement被添加的位置。追踪到AbstractMethod的抽象方法中。

找到了addMappedStatement()方法

而BaseMapper的所有方法(deleteById、delete、insert、select、update等)都继承了该抽象方法。

根据mapper方法(deleteById)显然是调用aDDDeleteMappedStatement方法。

这里我们可以发现,源码中根据不同的方法继承AbstractMethod实现了不同的实现类,并且实现了injectMappedStatement方法,sqlSource也是在这个地方被添加进配置文件。

4.2 AbstractMethod.inject

继续研究AbstractMethod抽象类,inject方法实现了自动注入sql的动作。

有上述源码可知,项目启动时,首先由默认注入器生成基础CRUD实现类对象,其次遍历实现类列表,依次注入各自的模板SQL,最后将其添加至mappedstatement。

五、SQL语句是怎么生成的?

5.1 SQL模板

上述方法中有两个关键的参数:SqlMethod、SqlSource;

继续研究源码发现:sqlMethod本质上是一个枚举类,存储了两个关键的元素:

BaseMapper中的方法名;

方法名对应的sql语句模板(即被标签包裹的字符串)。

到这里我们基本了解了mybaits-plus实现sql自动生成的本质:根据不同的方法来提供一些通用的模板,项目启动后再加载进mappedStatement。

5.2 SqlSource

此时SqlSource通过解析SQL模板、以及传入的表信息和主键信息构建出了SQL语句。

5.3 数据库表信息是如何获取的?

分析initTableName()方法:获取表名信息源码中传入了实体类信息clazz,其实就是通过实体上的@TableName注解拿到了表名;

我们在定义实体类的同时,指定了该实体类对应的表名。

分析initTableFields()方法:

获取主键及其他字段信息

至此tableInfo的信息已经注入完成了。

在研究完解析mapper的核心过程之后,我们再简单看下mapper文件被添加到configuration(mybatis核心配置文件)的过程。

六、mapper文件被添加的过程

ISqlInjector:Sql注入器

MybatisMapperAnnotationBuilder:mapper解析器

MybatisMapperAnnotationBuilder中的parse方法获取了sqlInjector(Sql注入器)来进行SQL注入。

Mybatis添加mapper的固有流程:MybatisMapperReGIStry

调用MapperAnnotionBuilder解析器进行解析

MybatisConfiguration.addMapper

MybatisXMLConfigBuilder.mapperElemnt

MybayisXMLConfigBuilder.parseConfiguration

添加mapper文件的过程分析到这里就完成了。

七、总结

7.1 流程梳理

下面总结梳理了一下mybatis-plus解析mapper文件自动注入sql的主要流程。

7.2 Mybatis-plus的ORM的核心思想

1)实体类和数据库表通过自定义注解来完成一一映射。

2)对象属性和字段同样使用注解来一一对应(命名注意要相同)。

3)为了提高复用性使得具体的mapper继承通用的增删改查接口。

4)利用模板方法和对象属性值动态拼接SQL。

八、参考文档

MyBatis-plus官方文档:https://mp.baomidou.com/

作者:vivo互联网服务器团队-Li Lei

到此这篇关于Mybatis-Plus的应用场景及注入SQL原理分析的文章就介绍到这了,更多相关Mybatis-Plus sql注入内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Mybatis-Plus的应用场景描述及注入SQL原理分析

本文链接: https://lsjlt.com/news/126813.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Mybatis-Plus的应用场景描述及注入SQL原理分析
    目录一、背景1.1 传统Mybatis的弊端1.2 MyBatis-Plus的定位1.3 特性1.4 原理解析二、准备工作2.1 基础接口BaseMapper2.2 创建实体类对象2...
    99+
    2024-04-02
  • Mybatis-Plus注入SQL原理分析
    目录前言案例测试原理解析前言 MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 那么 MyBat...
    99+
    2024-04-02
  • Mybatis防止sql注入原理分析
    目录Mybatis防止sql注入原理底层实现原理Mybatis解决sql注入问题小结一下Mybatis防止sql注入原理 SQL 注入是一种代码注入技术,用于攻击数据驱动的应用,恶意...
    99+
    2024-04-02
  • ThreadLocal原理分析及应用场景是怎样的
    本篇文章给大家分享的是有关ThreadLocal原理分析及应用场景是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1. ThreadLocal是什么?有哪些用途?首先介绍...
    99+
    2023-06-22
  • Java ThreadLocal原理解析以及应用场景分析案例详解
    目录ThreadLocal的定义ThreadLocal的应用场景ThreadLocal的demoTheadLocal的源码解析ThreadLocal的set方法ThreadLocal...
    99+
    2024-04-02
  • Zookeeper的基础原理及应用场景
    本篇内容介绍了“Zookeeper的基础原理及应用场景”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!简单了...
    99+
    2024-04-02
  • MySQL事务的原理及应用场景
    MySQL事务的原理及应用场景 在数据库系统中,事务是一组SQL操作的集合,这些操作要么全部成功执行,要么全部失败回滚。MySQL作为一种常用的关系型数据库管理系统,支持事务的特性,能...
    99+
    2024-03-02
    应用 mysql 事务
  • Oracle与SQL的区别及应用场景解析
    Oracle与SQL的区别及应用场景解析 在数据库领域,Oracle和SQL是两个常被提及的术语。Oracle是一种关系型数据库管理系统(RDBMS),而SQL(Structured ...
    99+
    2024-03-08
    应用场景 sql oracle
  • Mybatis-Plus中SQL语句组拼原理的的示例分析
    这篇文章主要为大家展示了“Mybatis-Plus中SQL语句组拼原理的的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Mybatis-Plus中SQL语句组拼原理的的示例分析”这篇文章...
    99+
    2023-06-15
  • 使用PDO防sql注入的原理分析
    前言 本文使用pdo的预处理方式可以避免sql注入。下面话不多说了,来一起看看详细的介绍吧 在php手册中'PDO--预处理语句与存储过程'下的说明: 很多更成熟的数据库都支持预处理语句的概念。什么是...
    99+
    2024-04-02
  • Javascript闭包使用场景的原理分析
    这篇文章给大家分享的是有关Javascript闭包使用场景的原理分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、闭包Javascript中,只有函数内部的子函数才能读取局部变量,闭包就是能够读取其他函数内部...
    99+
    2023-06-25
  • PHP开发缓存的原理及应用场景
    PHP开发缓存的原理及应用场景,需要具体代码示例随着互联网技术的发展,PHP已成为广泛应用的开发语言之一。在PHP开发中,使用缓存是一种常见的优化技术,可以减少数据库查询次数,缩短响应时间,提升应用性能。缓存原理缓存是一种将数据存储在内存中...
    99+
    2023-11-08
    缓存 原理 关键词:PHP
  • MySQL 的 SSL 连接优势及应用场景分析
    随着互联网的高速发展,数据传输的安全性也成为各个行业关注的焦点。在数据库管理系统中,MySQL是广泛使用的一种关系型数据库,其在数据存储和管理方面具有优势。然而,在数据传输过程中,可能存在安全隐患,因此,MySQL提供了SSL连接,以提高数...
    99+
    2023-10-22
    使用SSL连接可以加密通信
  • 阿里云ECS的应用场景及优势分析
    阿里云ECS(Elastic ComputeService)是阿里云提供的一种弹性计算服务,它可以满足各种不同应用场景下的需求。本文将介绍阿里云ECS的应用场景,并分析其优势。应用场景一:Web应用服务器阿里云ECS可以作为Web应用服务...
    99+
    2024-01-22
    阿里 场景 优势
  • mybatis返回map结果及@MapKey使用的场景实例分析
    本篇内容介绍了“mybatis返回map结果及@MapKey使用的场景实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!mybatis返...
    99+
    2023-06-28
  • PHP CLI与CGI的区别及应用场景比较分析
    PHP CLI与CGI的区别及应用场景比较分析 PHP是一种流行的服务器端脚本语言,通常用于创建动态网页内容。在PHP中,有两种主要的执行方式:命令行界面(CLI)和通用网关接口(CG...
    99+
    2024-03-10
    cgi php cli php脚本
  • Docker中Dockerfile多阶段构建原理及使用场景的示例分析
    小编给大家分享一下Docker中Dockerfile多阶段构建原理及使用场景的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!老版本Docker中为什么不支持多个 FROM 指令在17.05版本之前的Docker,只...
    99+
    2023-06-04
  • 深入理解Java中Filter的作用种类及应用场景
    目录如何使用FilterFilter的生命周期Filter执行顺序Filter细节自动登录BeanUtils的使用总结如何使用Filter 在Java Web应用程序中,使用Filt...
    99+
    2023-05-18
    Java Filter Java Filter作用
  • ASP 框架在 Linux 容器中的应用场景及优缺点分析。
    ASP 框架在 Linux 容器中的应用场景及优缺点分析 ASP(Active Server Pages)是一种基于服务器端的动态网页技术,它将 HTML 页面和脚本语言(如 VBScript 或 JavaScript)结合起来,实现了网页...
    99+
    2023-08-25
    框架 linux 容器
  • 自然语言处理在Go语言中的应用场景分析
    自然语言处理(NLP)是一种涵盖语音识别、机器翻译、文本分类、信息提取等多个领域的技术。在当今信息化时代,NLP技术的应用越来越广泛,涉及到的领域也越来越多。在这些应用场景中,Go语言作为一种高效的编程语言,也在NLP技术中发挥着越来越重...
    99+
    2023-09-28
    对象 自然语言处理 异步编程
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作