首页 > 其他分享 >mybatis-plus mapper整理

mybatis-plus mapper整理

时间:2024-05-16 23:40:40浏览次数:21  
标签:xml mapper 扫描 bean plus mybatis org 加载

mybatis-plus mapper整理

简介

提供了操作数据的框架,避免使用jdbc操作数据,加速开发效率,支持多种数据库(databaseId)。既支持sql,mapper的编写,也支持注解@Select等,同时提供了一二级缓存,以及BaseMapper接口以及IService、ServiceImpl这些接口,来提供模板化的方法。同时还支持逆向工程生成代码,是很好用的dao层框架。

用例

  • spring-boot-starter-jdbc
  • mysql-connector-java
  • druid
  • mybatis-plus-boot-starter

    解析

    依赖信息

     <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.13</version>
    </dependency>
    
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.0</version>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    

    使用过程

  • 我们使用时通常加入@mapperScan注解扫描一个basePackage, 或是 @Mapper注解指定一个mapper接口类
  • 而调用时,就是自动注入 mapper接口类 bean 然后调用bean方法,或是 使用session.getMapper() 进行方法调用。

    依据上面的使用过程解读代码

    解读1:扫描mapper接口类的bean定义

  • 容器启动,扫描bean定义,加载 mapper接口类注册成bean
    1. 容器启动时,扫描bean定义:invokeBeanFactoryPostProcessors(beanFactory);
    2. 代码中使用了@MapperScan,就会加载MapperScannerRegistrar
    3. MapperScannerRegistrar会加载MapperScannerConfigurer
    4. MapperScannerConfigurer引入ClassPathMapperScanner,进行basePackage扫描。 这里会区分:如果是 @MapperScan,那么basePackage就是里面的属性,且不会添加includeFilter;而如果使用@Mapper,那么basePackage就是启动类的包路径,添加@Mapper作为includeFilter。
    5. ClassPathMapperScanner扫描完成后,会执行processBeanDefinitions()修改bean定义,将beanClass设置为 MapperFactoryBean 实现了FactoryBean接口,作为工厂bean,实例化时会调用getObject方法来获取实际bean。而getObject会获取 MybatisConfiguration.getMapper(),也就是读取xml时放入mapper映射的位置(解读3)

    解读2,实例化mapper接口类时,加载sqlSessionFacory

  • 容器启动,实例化剩余bean,由于bean依赖sqlSessionFactory,触发加载
    1. 容器启动,实例化剩余bean:finishBeanFactoryInitialization
    2. 实例化mapper,依赖于sqlSessionFactory,就需要加载 com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration#sqlSessionFactory()
    3. 加载sqlSessionFacory会加载 容器中的实现了inteceptor接口的bean,放入到 InterceptorChain。后话:这个InterceptorChain后面在调用时会用Plugin工具代理 Executor、StatementHandler、ResultSetHandler、ParameterHandler等。
    4. 加载sqlSessionFacory会扫描 配置项定义的mybatis-plus.mapper-locations,作为xml存放的路径,作为resource扫描这个文件夹下的xml文件。(如果没有设置,就是用默认的/mapper/**/*.xml)。

    解读3,加载sqlSessionFacory时,扫描xml,生成mapper映射表和各个方法的mapperStatement

  • 扫描xml文件,解析各个标签,最终生成mapper到MybatisMapperProxyFactory的映射
    1. 解析 mapper标签,作为一个xml文件
    2. 解析里面的cache标签,生成cache链,PerpetualCache <- LruCache <- SerializedCache <- LoggingCache <- SynchronizedCache,并存起来等mapperStatement注册时用。
    3. 解析里面的parameterMap、resultMap、sql、select|insert|update|delete标签,其中sql语句解析时使用 mixSqlNode, 解析各个子标签foreach,trim等等。解析完成后将这个方法,使用 nameSpace+id将方法注册成一个 mapperStatement。这个mapperStatement会带上上面的 cache 数据。 所以有cache数据的mapperStatement就是使用了二级缓存的。
    4. 完成解析后,注册这个mapper:bindMapperForNamespace。注册 mapper 到 MybatisConfiguration,也就是 MapperFactoryBean.getObject之后会执行的 MybatisConfiguration.getMapper(解读1)。存放 clazz, MybatisMapperProxyFactory 的映射关系

    解读4,实例化mapper接口类时,创建代理类

  • 由 bean定义中的 MapperFactoryBean.getObject(),执行到 MybatisConfiguration .getMapper() 获得 存在的mapper映射关系得到 MybatisMapperProxyFactory。
  • 然后由 MybatisMapperProxyFactory.newProxyInstance(),使用 MapperProxy 作为拦截器。

    解读5,调用时被MybatisMapperProxy拦截,以及缓存读取

  • MapperProxy 就会拦截这个mapper下的方法,执行时会判断mapperstatement类型,如果是查询,就判断 mapperstatement上有没有带cache数据,如果没有说明没使用标签。如果有,就可以走 二级缓存存取。
  • 之后就开始查询,就需要 openSession().execute(), 这里就需要newExecutor(),而 newExeCutor()时,会使用 InterceptorChain, 创建代理类,形成拦截链。

    总结

    第一部分:

    加载mapper接口类,并注册bean为mapperFactoryBean。

    第二部分:

    加载sqlSessionFacory, 读取xml文件,作为mapper到mybatisMapperProxyFactory的映射表,存入到 MybatisConfiguration。

    第三部分:

    MapperFactoryBean.getObject(),会读取MybatisConfiguration.getBean(),从而获取到 mybatisMapperProxyFactory 映射表中的这个value,然后 使用这个 mybatisMapperProxyFactory 创建代理类,使用 mapperProxy 作为拦截器,用于拦截mapper方法。

    额外部分:

  • 读取xml时,获取cache链配置。
  • 加载sqlSessionFacory, 获取容器中的 Interceptor, 收集到 InterceptorChain。在newExecutor/StatementHandler/....时多层代理。

    感受

  • 一些重要方法没有特别好的标识,阅读时会容易轻视忽略掉。例如:
    1. 缓存链的生成(org.apache.ibatis.mapping.CacheBuilder#build)
    2. sqlSessionFactory的构建,含了xml数据的读取(com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean#buildSqlSessionFactory)
    3. sql标签的读取(org.apache.ibatis.scripting.xmltags.XMLLanguageDriver#createSqlSource(org.apache.ibatis.session.Configuration, org.apache.ibatis.parsing.XNode, java.lang.Class))
  • 使用了设计模式。例如:
    1. cache的责任链
    2. InterceptorChain, 使用plugin工具包装层层target。(org.apache.ibatis.plugin.InterceptorChain#pluginAll)
    3. MybatisMapperProxyFactory.newInstance(),内部还是使用的jdk动态代理,使用mapperProxy作为拦截器。(org.apache.ibatis.binding.MapperProxyFactory#newInstance(org.apache.ibatis.session.SqlSession))
  • 巧妙运用了spring-boot的一些加载机制
    1. 加载MapperScannerConfigurer的bean定义,再加载ClassPathMapperScanner,用于扫描Mapper,并修改bean定义为MapperFactoryBean。再触发getObject,拿到存储起来的 MybatisConfiguration的 knowmappers 和 mapperStatements等。
  • 对设计模式和类加载有挺好的参考价值。
  • 标签:xml,mapper,扫描,bean,plus,mybatis,org,加载
    From: https://www.cnblogs.com/ITket/p/18197004

    相关文章

    • 整合mybatis框架
      添加依赖<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>xxx</version></dependency>添加配置文件mybatis:mapper-locations:class......
    • LLM-通义千问:MyBatis-Plus 多租户插件
      MyBatis-Plus(简称MP)是一个对MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。多租户(Multi-Tenant)是一种软件架构技术,它允许多个组织(即“租户”)共享同一应用程序的实例,但每个组织的数据都是隔离且私有的。在多租户场景下,MyBatis-Plus提供了一种插件......
    • vue3 elementplus样式
      科技感日期选择器样式.data_screen.el-picker-panel__footer{color:#87CEEB;background:#00122a;border-top:1pxsolid#274954;}.data_screen.el-picker-panel{color:#87CEEB;background:#00122a;border:1pxsolid#274954;}.data_screen.el-picker-pane......
    • MyBatis-Plus 实现多租户管理的实践
      本文主要讲解使用Mybatis-Plus结合dynamic-datasource来实现多租户管理在现代企业应用中,多租户(Multi-Tenant)架构已经成为一个非常重要的设计模式。多租户架构允许多个租户共享同一应用程序实例,但每个租户的数据彼此隔离。实现这一点可以大大提高资源利用率并降低运营成本。在本......
    • mybatis及mybatis-plus的实体映射
      packagecom.duxiang.backgroundmanagement.entity;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;1.mybatisimportjavax.persistence.*;@Data@AllArgsConstructor@NoArgsConstructor@Table(name="m_chat")/......
    • Mybatis-Plus中 updateById 无法将已有值的字段更新为 null
      在MyBatis-Plus中,使用updateById,null字段并不会更新,其实是和更新的策略有关,当然,也有插入策略。1、调整全局策略(会对所有的字段都忽略判断,如果一些字段不想要修改,但是传值的时候没有传递过来,就会被更新为null)mybatis-plus:global-config:db-config:insert-stra......
    • vue3+ts+elementPlus项目搭建
      1.cmd+R  查看是否安装node环境和vue,node-v  出现版本号如果没有,去下载安装,地址: Node.js—DownloadNode.js®(nodejs.org)vue-V   出现版本号如果没有, 输入命令行,全局安装或升级脚手架npminstall-g@vue/cli2.创建vue项目  (项目名......
    • Windows+Pycharm+Flask+Vue+Element-Plus 前后端分离实现分写查询功能
      准备工作安装nodejshttps://nodejs.cn/download/验证是否安装成功安装Python不赘述,3.7+Pycharm创建Flask项目D:\pythonProject\myvueWindowsPowerShell进入到CMD指令界面,cdD:\pythonProject\myvue进入到myvue目录,创建vue项目文件client,然后cd到client目录,安装vue......
    • Mybatis使用cache-ref需注意的问题
      https://blog.csdn.net/Ewan_/article/details/1298659741.在MapperXML中使用<cache-ref>标签UserCacheMapperXML需要有<cache>标签,如果没有则会爆Exceptioninthread"main"org.apache.ibatis.builder.IncompleteElementException:Nocachefornamespace'......
    • 用友畅捷通TPlus-keyEdit.aspx接口存在SQL注入漏洞
      漏洞描述:该漏洞是由于畅捷通T的/tplus/UFAQD/keyEdit.asp接口处未对用户的输入进行过滤和校验,未经身份验证的攻击者可以利用SQL注入漏洞获取数据库中的信息fofa:app="畅捷通-TPlus"POC:GET/tplus/UFAQD/keyEdit.aspx?KeyID=1%27%20and%201=(select%20@@version)%20--&preloa......