Springboot integrated mybatis custom plug-in development

What is mybatis plugin

The mybatis plug-in is a way to intercept and enhance specific methods and do some additional processing when performing database operations.
The enhanced principle of the myabtis plug-in is realized by the use of dynamic agents, which can intercept the execution classes of database operations. The execution classes of several operation databases in mybatis are:

Executor
StatementHandler 
ParameterHandler
ResultSetHandler

Among them:
Executor is the general executor, he is like a master, used to coordinate and manage other executors.
StatementHandler is the executor used to generate Statement or PreparedStatement. At the same time, he will call ParameterHandler to set the parameters in the SQL statement. After the value is set, it will call SQL to execute in the database through StatementHandler, and finally return a result set through ResultSetHandler Map the result set and the corresponding entity to fill in the data, and then return the result entity to the StatementHandler.

Therefore, we intercept these executors, such as the interception of StatementHandler, that is, interception of sql operations, the following is an example of interception of this StatementHandler.

Instance

demand

Intercept all methods where the database SQL execution time exceeds 1 millisecond, and record the SQL.

achieve

Plug-in class
@Intercepts({
        @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
})
public class MyPlugin implements Interceptor {

    private long time;


    //方法拦截
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //通过StatementHandler获取执行的sql
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = statementHandler.getBoundSql();
        String sql = boundSql.getSql();

        long start = System.currentTimeMillis();
        Object proceed = invocation.proceed();
        long end = System.currentTimeMillis();
        if ((end - start) > time) {
            System.out.println("本次数据库操作是慢查询,sql是:" + sql);
        }
        return proceed;
    }

    //获取到拦截的对象,底层也是通过代理实现的,实际上是拿到一个目标代理对象
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    //获取设置的阈值等参数
    @Override
    public void setProperties(Properties properties) {
        this.time = Long.parseLong(properties.getProperty("time"));
    }
}

Myabtis custom plug-ins only need to implement the Interceptor interface, and annotate @Intercepts and @Signature to configure the objects that need to be intercepted, where type is the object Class to be intercepted, method is the method in the object, and args is the method parameter type.

Inject plugins into the interception chain

There are two ways to inject

Method 1: Direct injection

@org.springframework.context.annotation.Configuration
@MapperScan({"com.springboot.demo.mapper"})
public class MapperConfig {

    //注册插件
    @Bean
    public MyPlugin myPlugin() {
        MyPlugin myPlugin = new MyPlugin();
        //设置参数,比如阈值等,可以在配置文件中配置,这里直接写死便于测试
        Properties properties = new Properties();
        //这里设置慢查询阈值为1毫秒,便于测试
        properties.setProperty("time", "1");
        myPlugin.setProperties(properties);
        return myPlugin;
    }
}

Method 2: Add to the interception chain through myabtis configuration
@org.springframework.context.annotation.Configuration
@MapperScan({"com.springboot.demo.mapper"})
public class MapperConfig {
    //将插件加入到mybatis插件拦截链中
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return new ConfigurationCustomizer() {
            @Override
            public void customize(Configuration configuration) {
                //插件拦截链采用了责任链模式,执行顺序和加入连接链的顺序有关
                MyPlugin myPlugin = new MyPlugin();
                //设置参数,比如阈值等,可以在配置文件中配置,这里直接写死便于测试
                Properties properties = new Properties();
                //这里设置慢查询阈值为1毫秒,便于测试
                properties.setProperty("time", "1");
                myPlugin.setProperties(properties);
                configuration.addInterceptor(myPlugin);
            }
        };
    }
}

test

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_28822933/article/details/85224109