Giter VIP home page Giter VIP logo

mybatis-plugin-spring-boot's Introduction

Build Status codecov

基于配置增强 SQL 组件设计概述

思维导图

一、概述

SQL增强插件可以做到一些统一的SQL处理逻辑,比如现在比较流行的基于多租户的PAAS平台,都会涉及到在数据库层的资源隔离,就需要在所有的执行语句中加入一个统一的WHERE条件,就可以使用这个插件来实现,免去重复书写SQL

​ 引入POM依赖之后还需要配置Enabletrue才能开启使用。

使用场景

​ 使用场景

二、校验规则

​ 校验规则是用于校验当前的SQL是否符合当前的规则,当有多个校验规则时,会顺序的执行校验,直到校验完为止。

校验规则级别

​ 校验规则目前支持如下的级别:

  • databases:对应数据库明字段;如果值是databases是依赖写的SQL中表前面有库的值,否则取不到库名来校验。
  • table:对应执行的表明,内置了一个关键字all,意味着执行所有的表。
  • dml:那么对应的值如果不是selectinsertupdatedelete那规则就会校验失败。

三、执行规则

1、规则策略

​ 内置的规则策略有如下几种,每种规则策略都有对应的实现,并且可以扩充自定义的规则实现。

  • add_where_field: 符合次规则的 sql 语句都会加上统一的 where 条件。
  • add_insert_field: 在插入语句中添加如下的字段进行插入。
  • add_update_field: 在更新语句中添加如下的字段进行插入。
  • add_field: 添加字段,在插入时加入这个字段,更新时加入这个字段。

2、字段获取策略

​ 执行规则获取字段策略,就是此字段可以从多个地方获取,目前支持如下几种策略。

  • conf: 从配置文件中获取。
  • threadLocal: 从本地线程变量中获取。
  • customer: 自定义类,从自定义类中获取。

3、字段值获取策略

​ 执行规则获取字段值策略,就是次字段值可以从多个地方获取,目前支持如下几种策略。

  • conf: 从配置文件中获取。
  • threadLocal: 从本地线程变量中获取。
  • customer: 自定义类,从自定义类中获取。

4、获取失败后的执行策略

​ 就是上面从各种策略中获取字段值失败后的执行策略;目前支持如下两种策略.

  • run : sql会继续运行,执行SQL时不会加入预期的字段。
  • stop: sql会抛出异常,终止当前运行的SQL

四、SQL 拦截原理

SQL拦截是基于Mybais拦截器来实现的。Mybatis Plugin 使用责任链模式与代理模式实现。

责任链模式

​ 责任链模式的实现包含处理器接口Handler或者抽象处理器类AbsHandler, 还包括一个处理器链的类HandlerChain,这个处理器链类一般包括三个方法,一个是注册处理器的方法void addHandler(Handler handler),还有一个遍历执行处理器的方法void handlerAll(),以及一个返回所有注册了处理器对象的方法List<Handler> getHandlers(),此方法一般需要放回不可修改的数据类,使用Collections.unmodifiableList进行包装。

​ 对应到Mybatis中的责任链模式的处理器接口就是Interceptor,处理器链就是InterceptorChain,处理器链中的处理器注册是在解析XML配置时进行执行的。对应到源码为XMLConfigBuilder parseConfiguration() 方法中的pluginElement(root.evalNode("plugins")); 处理器接口中暴露了三个方法,实际使用的处理器方法是Object plugin(Object target);

​ 然后处理器链 InterceptorChain pluginAll 方法是分别被ExecutorParameterHandlerResultSetHandlerStatementHandler这四个对象调用的。

代理模式

​ 代理模式有被代理对象和代理人两个角色,对应到Mybatis的插件模式中就是Plugin是代理人的角色,Plugin中的private Object target属性就是被代理对象,这个代理对象的创建是通过Plugin wrap()方法来创建的;这个方法是在责任链调用的时候通过处理接口中的Object plugin(Object target);方法进行调用的。

为什么Mybatis的插件功能使用了责任链和动态代理来实现?

我的思考:参考Spring种的过滤器或者拦截器使用的责任链都发现,处理器接口比较单一,且参数高度封装;但是反观Mybatis中需要使用责任链执行的方法,如ExecutorStatementHandlerParameterHandlerResultSetHandler方法较多且参数各不统一,如果能统一对这些方法都执行责任拦截,想到的简单方法就是使用动态代理,把每个方法抽象为方法名、方法参数、方法返回值。这样就有统一的抽象实体了,然后责任链统一对抽象实体来进行处理即可。

五、SQL 解析原理

SQL解析是基于jsqlparser组件来实现的。

六、版本更新记录

  • 1.0.0 实现了运行前的 SQL改变,更多的是加入某个字段到SQL中去。最典型的应用场景是数据多租户隔离,2020-08-30 发布
  • 1.1.0 加入修改SQL执行前和执行后的值,最典型的应用场景是数据加解密,入库前加密,查询结果之后解密。待定2020-10-07 发布

mybatis-plugin-spring-boot's People

Contributors

orangeyts avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.