1. MyBatis is what

MyBatis is an ORM (Object Relational Mapping) framework, in which the Object data in the Java code we wrote is the Object model, and the table data in the Relational database is the Relational model. MyBatis interacts with relational database through JDBC interface. The main function is to complete the mapping between object model and relational model according to the mapping configuration file, which reduces the repetitive code of pure JDBC development and only exposes simple API for developers to use.


2. What is a plug-in

Plug-ins are a common extension method, and most open source frameworks allow users to add custom plug-ins to extend or change the functionality of the framework. Mybatis also provides the function of plug-in, although called plug-in, but is actually implemented by Interceptor. In MyBatis plug-in module involved in the chain of responsibility mode and JDK dynamic proxy knowledge, the following will analyze the chain of responsibility mode and JDK dynamic proxy in MyBatis plug-in module practice.


3. Introduction of responsibility chain model

The chain of responsibility pattern is used to deal with situations where a client sends a request and multiple objects have the opportunity to process the request, but the client does not know who will handle the request. That is, the requester and receiver need to be decoupled so that receivers can be dynamically switched and combined. Note that in the chain of responsibility mode, the request is not necessarily processed, because there may be no suitable handler, and the request is passed from beginning to end in the chain of responsibility, with each handler deciding that it does not belong to its own processing, and the request has no object to process. The structure diagram of the chain of responsibility model is as follows:

 





When a request comes in, it passes through HandlerOne’s handlerRequest method, passing the request to HandlerTwo, passing the request to HandlerThree, and so on, forming a chain. The responsibility of each object in the chain is different, which is the responsibility chain model.



4. Interceptors in MyBatis 

(1) The point of use of interceptors

MyBatis allows users to intercept a point in the execution of an SQL statement using a custom interceptor. By default, MyBatis allows interceptors to intercept Executor methods, ParameterHandler methods, ResultSetHandler methods, and StatementHandler methods. MyBatis = MyBatis = MyBatis The Executor, ParameterHandler, ResultSetHandler, and StatementHandler are all required core layers for MyBatis SQL operations. It is in the implementation classes of these interfaces that our interceptors come into play. Specific interception methods are as follows:

The Executor.

         Update (), Query (), flushStatements(), COMMIT (), rollback(), getTransaction(), close(), isClosed() methods.

ParameterHandler:

        The getParameterObject() and setParameters() methods.

ResultSetHandler:

        The handleResultSets() and handleOutputParameters() methods.

StatementHandler:

        The prepare(), parameterize(), Batch (), update(), and query() methods.

 

(2) Interceptor definition

Public interface Interceptor {// Execute the Interceptor method Object Intercept (Invocation) throws Throwable; Mybatis plugin.wrap (...) This method internally determines whether the current interceptor matches the current interceptor, creates a proxy object if it does, and returns the current object if it does not. Object plugin(Object target); // When mybatis loads the initialization, it will fetch the configuration value from the interceptor based on the configuration of XML or annotationssetProperties(Properties properties); 

}Copy the code

Our custom interceptor needs to implement this interface and be configured in MyBatis to take effect.



(3) Interceptor chain

Public class InterceptorChain {// All configured interceptors private final List<Interceptor> interceptors = new ArrayList<>(); public Object pluginAll(Object target) {for (Interceptor interceptor : interceptors) { 
            target = interceptor.plugin(target); 
        } 
        returntarget; } // When mybatis loads initialization, it creates interceptors based on the configuration of XML or annotations. Public void addInterceptor(Interceptor Interceptor) {interceptors.add(Interceptor); } public List<Interceptor>getInterceptors() { 
        returnCollections.unmodifiableList(interceptors); }}Copy the code

When loading the configuration file, MyBatis places all configured interceptor objects (including custom interceptors) in the field interceptors of the InterceptorChain class object for subsequent operations. In the pluginAll method of the InterceptorChain, loop the interceptors and call the interceptor.plugin(target) method. The plugin method internally determines whether the Target matches the current interceptor object. If it does, it uses the JDK dynamic proxy to create a proxy object for the target object. Otherwise, it returns an unproxyed target object. Here is the cyclic interceptors, so each interceptor executes the plugin method once, Plugin (target) returns the value of the last interceptor.plugin(target) call as an input to the next interceptor.plugin(target). The net result is that target may be proxied multiple times. The diagram below:







As it turns out, the final target object is probably one that has been proxied many times, namely the interceptorProxy1 object in the figure. When the interceptorProxy1 executes the interceptor method, it calls the interceptor method of the interceptorProxy2 object. The interceptorProxy2 interceptor method continues downward until the final target object is called. As you can see, the target object matches all of its appropriate interceptor objects, and then flows through all of the matching interceptor objects. This can be understood as the design of the chain of responsibility model.



5. To summarize

Plugin (target) interceptor (interceptor, target); interceptor (interceptor, target); interceptor (interceptor, target); interceptor (interceptor, target); interceptor (interceptor, target); interceptor (interceptor, target); interceptor (interceptor, target); The internal logical implementation of the agent.