MyBatis plug-in and sample----print each SQL statement and its execution time

Source: Internet
Author: User
Tags prepare

Pick a piece of text from MyBatis official documents.

MyBatis allows you to intercept a call that has been executed by a mapped statement at some point. By default, MyBatis allows the use of plug-ins to intercept method calls

    • Executor (update, query, Flushstatements, Commint, Rollback, gettransaction, close, isClosed)
    • Parameterhandler (Getparameterobject, Setparameters)
    • Resultsethandler (Handleresultsets, Handleoutputparameters)
    • Statementhandler (Prepare, parameterize, batch, update, query)

The details of the methods in these classes can be found by looking at the signatures of each method, and their source code exists in the MyBatis release package. You should understand the behavior of the method you are overriding, assuming that you are doing more than the monitoring call. If you try to modify or overwrite a given method, you may break the core of MyBatis. This is a low-level class and method, use plug-ins with caution.

Plug-in Example: print each SQL statement and its execution time

The following code shows how to use the MyBatis plug-in, and the scenario to be demonstrated is to print each actual SQL statement and the time it executes. This is a very useful requirement, and the log of MyBatis itself can record SQL, but there are several issues:

    1. MyBatis log printed SQL log, parameters are placeholder "?" Replace, you cannot know what the parameters in the SQL statement are actually executed
    2. MyBatis log printed SQL log, there are a large number of line breaks, usually a SQL statement to be displayed through more than 10 lines, the reading experience is very poor
    3. Unable to log SQL execution time, with SQL execution time to pinpoint SQL with slow execution time

Write MyBatis plug-in is very simple, only need to implement interceptor interface, I here will my interceptor named Sqlcostinterceptor:

Press CTRL + C to copy the code<textarea></textarea>Press CTRL + C to copy the code

Analyze This code (this is a modified version, mainly increased to select * from XXX where ID in <foreach collection= "list" >...</foreach> This notation placeholder is replaced with support for true parameters).

The first is annotations @intercepts and @signature, both of which are necessary because the Wrap method of plugin takes the arguments in both annotations. Multiple @signature can be defined in the @Intercepts, and a @signature indicates that a method that meets the following conditions will be intercepted:

    • The interface must be of type definition
    • Method names must be consistent with methods
    • The class type of the method parameter must be in the same order as the Args definition class type

The next question is: There are four interfaces to intercept, why use Statementhandler to intercept? According to the name of Parameterhandler and Resultsethandler, the former processing parameters, the latter processing results is impossible to use, the rest is executor and statementhandler. The reason for intercepting Statementhandler is not to use executor because:

    • Executor's update and query methods may use the MyBatis level one or two cache, which results in a statistically not true SQL execution time
    • Statementhandler's update and query methods will, in any case, be counted to PreparedStatement's Execute method execution time, although there are also some errors (the error is mainly from the time of processing results will be counted), but the difference is not small

Then talk about the SetProperties method, you can configure some configuration properties in the <plugin></plugin> sub-label <property/>, all the configuration properties are in the parameter properties, The SetProperties method can get the configured properties for the required processing.

Then talk about the plugin method, here is the target interface generation agent, do not need and do not have to write the method of the generation agent, MyBatis's plugin class has provided us with the Wrap method (of course, if you have their own logic can also be added before and after the Plugin.wrap method, but ultimately must use the Plugin.wrap method to build the proxy), look at the implementation of this method:

1 public static object Wrap (object target, Interceptor Interceptor) {2     map<class<?>, set<method>> Signaturemap = Getsignaturemap (Interceptor); 3     class<?> type = Target.getclass (); 4     class<?>[] interfaces = getallinterfaces (type, Signaturemap ); 5     if (Interfaces.length > 0) {6       return proxy.newproxyinstance (7           Type.getclassloader (), 8           interfaces, 9           new Plugin (Target, Interceptor, Signaturemap));     }11     return target;12}

Because target here must be an interface, it is safe to use the proxy class provided by the JDK itself, which is equivalent to generating a proxy for the interface if it satisfies the method signature.

Finally is the Intercept method, here is the core of the Interceptor Code, the method of logic I do not explain, you can see for yourself, the only thing to note is that in any case eventually must return to Invocation.proceed (), Ensure that the interceptor is called at the layer level.

XML file configuration is an effect demo

Once you've finished writing the plugin, you just need to configure it once in the config. ins file, very simple:

1 <plugins> 2     <plugin interceptor= "Org.xrq.mybatis.plugin.SqlCostInterceptor"/> 3 </plugins>

Here each <plugin> child tag represents a plugin, interceptor represents the full path of the interceptor, different for each person.

With classes and this configuration, you can use Sqlcostinterceptor, Sqlcostinterceptor is generic, but everyone's crud is different, I print the results of my crud execution here:

Sql:[insert into Mail (IDs, Create_time, Modify_time, web_id, mail, use_for) VALUES (null, now (), now (), "1", "[Email protect Ed] "," personal use ");] Execution time-consuming [1ms]sql:[insert into mail (ID, create_time, modify_time, web_id, mail, use_for) VALUES (null, now (), now (), "2", "[Emai L protected] "," Enterprise Use ");] Execution time-consuming [1ms]sql:[insert into mail (ID, create_time, modify_time, web_id, mail, use_for) VALUES (null, now (), now (), "3", "[Emai L protected] "," Registered account Use ");] Execution time-consuming [0ms]

See the full SQL statement printed and the SQL statement execution time.

However, to illustrate the point, this plugin is just a simple demo, I did not fully tested, should not be able to cover all the scenes, so if you want to use this snippet of code to print the real SQL and its execution time of the friends, but also need to make changes on this basis, but even if the code is not changed, This plug-in to beautify the role of SQL, remove some line break or no problem.

As for the MyBatis plug-in implementation principle, will be in my "MyBatis Source Analysis" series of articles in detail, the article address for "MyBatis Source code Analysis" plug-in implementation principle.

Postscript

MyBatis plug-in mechanism is very useful, well-used can solve a lot of problems, not just the print SQL statement here and record the execution time of SQL statements, paging, sub-table can be implemented through plug-ins. The key to good use of plug-ins is my first list, here again:

    • Executor (update, query, Flushstatements, Commint, Rollback, gettransaction, close, isClosed)
    • Parameterhandler (Getparameterobject, Setparameters)
    • Resultsethandler (Handleresultsets, Handleoutputparameters)
    • Statementhandler (Prepare, parameterize, batch, update, query)

Only by understanding what these four interfaces and related methods do, can we write good interceptors and develop the functions that are expected.

Original address: http://www.cnblogs.com/xrq730/p/6972268.html

MyBatis plug-in and sample----print each SQL statement and its execution time

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.