In daily development, mybatis has become an important role in implementing the data persistence layer. The following is the implementation of a paging plug-in developed using mybatis. For more information about the plug-in concept of mybatis, see the mybatis website.
You can see from the official website that mybatis allows you to intercept the following methods.
- Executor (Update, query, flushstatements, commit, rollback, gettransaction, close, isclosed)
- Parameterhandler (getparameterobject, setparameters)
- Resultsethandler (handleresultsets, handleoutputparameters)
- Statementhandler (prepare, parameterize, batch, update, query)
Using the plug-in is very simple. You only need to implement the interceptor interface and specify the method signature you want to interceptor.
// ExamplePlugin.java@Intercepts({@Signature( type= Executor.class, method = "update", args = {MappedStatement.class,Object.class})})public class ExamplePlugin implements Interceptor { public Object intercept(Invocation invocation) throws Throwable { return invocation.proceed(); } public Object plugin(Object target) { return Plugin.wrap(target, this); } public void setProperties(Properties properties) { }}<!-- mybatis-config.xml --><plugins> <plugin interceptor="org.mybatis.example.ExamplePlugin"> <property name="someProperty" value="100"/> </plugin></plugins>
Explanation of tutorials on the official website:
- User-Defined interceptor class needs to be implementedInterceptorInterface.
- Specifies the method that the interceptor needs to intercept.
ExamplePlugin
YesExecutor
. ViewExecutor
The source code is as follows:
Int Update (mappedstatement MS, object parameter) throws sqlexception;
- Configuration File
The implementation of the paging plug-in is as follows:Executor
Java <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
Method interception.
1. Define the interceptor class to implementInterceptor
Interface to specify the method to intercept.
@ Intercepts ({@ signature (type = executor. class, method = "query", argS = {mappedstatement. class, object. class, rowbounds. class, resulthandler. class}) public class pageinterceptor implements interceptor {static int partition = 0; static int parameter_index = 1; static int rowbounds_index = 2; static int result_handler_index = 3; dialect; public object intercept (Invocation I Nvocation) throws throwable {processintercept (invocation. getargs (); Return invocation. proceed ();} void processintercept (final object [] queryargs) {mappedstatement MS = (mappedstatement) queryargs [mapped_statement_index]; object parameter = queryargs [parameter_index]; // obtain the page information rowbounds final rowbounds = (rowbounds) queryargs [rowbounds_index]; int pagecurrent = rowbounds. getoffset (); Int pagesize = rowbounds. getlimit (); // obtain the namespace and method string [] namespaceid = Ms. GETID (). Split ("\."); If (! Arrayutils. isempty (namespaceid) & namespaceid [namespaceid. Length-1]. startswith ("query") {If (dialect. supportslimit () & (pagecurrent! = Rowbounds. no_row_offset | pagesize! = Rowbounds. no_row_limit) {boundsql = Ms. getboundsql (parameter); string SQL = boundsql. getsql (). trim (); If (dialect. supportslimitoffset () {SQL = dialect. getpagesql (SQL, pagecurrent, pagesize); pagecurrent = rowbounds. no_row_offset;} else {SQL = dialect. getpagesql (SQL, 0, pagesize);} pagesize = rowbounds. no_row_limit; queryargs [rowbounds_index] = new rowbounds (pagecurrent, pagesize ); Boundsql newboundsql = new boundsql (Ms. getconfiguration (), SQL, boundsql. getparametermappings (), boundsql. getparameterobject (); mappedstatement newms = copyfrommappedstatement (MS, new boundsqlsqlsource (newboundsql); // you need to assign metaparameters values in the past .. metaobject countbsobject = systemmetaobject. forobject (newboundsql); metaobject boundsqlobject = systemmetaobject. forobject (boundsql); countbsobject. setvalu E ("metaparameters", boundsqlobject. getvalue ("metaparameters"); queryargs [mapped_statement_index] = newms ;}}/ ** @ see mapperbuilderassistant */private mappedstatement copyfrommappedstatement (mappedstatement MS, sqlsource newsqlsource) {Builder = new mappedstatement. builder (Ms. getconfiguration (), Ms. GETID (), newsqlsource, Ms. getsqlcommandtype (); builder. resource (Ms. getresource (); Bui Lder. fetchsize (Ms. getfetchsize (); builder. statementtype (Ms. getstatementtype (); builder. keygenerator (Ms. getkeygenerator (); builder. keyproperty (Ms. getkeyproperties () = NULL? Null: Ms. getkeyproperties () [0]); builder. timeout (Ms. gettimeout (); builder. parametermap (Ms. getparametermap (); builder. resultmaps (Ms. getresultmaps (); builder. resultsettype (Ms. getresultsettype (); builder. cache (Ms. getcache (); builder. flushcacherequired (Ms. isflushcacherequired (); builder. usecache (Ms. isusecache (); Return builder. build ();} public object plugin (object target) {return plugin. wrap (target, this);} public void setproperties (properties Properties) {try {string dialectclassvalue = properties. getproperty ("dialectclass"); If ("com. page. dialect. mysqldialect ". equals (dialectclassvalue) {dialect = (dialect) class. forname (mysqldialect. class. getcanonicalname ()). newinstance ();} else {dialect = (dialect) class. forname (oracledialect. class. getcanonicalname ()). newinstance () ;}} catch (exception e) {Throw new runtimeexception ("cannot create dialect instance by dialectclass:" + oracledialect. class. getcanonicalname (), e) ;}} public static class boundsqlsource implements sqlsource {boundsql; Public boundsqlsource (boundsql) {This. boundsql = boundsql;} public boundsql getboundsql (Object parameterobject) {return boundsql ;}}}
/*** Similar to dialect of hibernate, but only the paging part is simplified */public class dialect {/*** converts the SQL statement into a paging SQL statement </BR> * Splits the original SQL statement, assemble the required paging SQL. */Public String getpagesql (string SQL, int pagecurrent, int pagesize) {Throw new unsupportedoperationexception ("paged queries not supported");} public Boolean supportslimit () {return false ;} public Boolean supportslimitoffset () {return supportslimit ();}}
Public class mysqldialect extends dialect {Public String getpagesql (string SQL, int pagecurrent, int pagesize) {// original SQL string orgsql = SQL. trim (); // reset the current page pagecurrent = pagecurrent-1; // start data row int offset = pagecurrent * pagesize; // final SQL stringbuffer finalesql = new stringbuffer (); finalesql. append ("select * from ("); // append the original SQL statement finalesql. append (orgsql); // use limit to paging finalesql. append ("Limit" + String. valueof (offset) + "," + String. valueof (pagesize); finalesql. append (") as tabletotal"); Return finalesql. tostring ();} public Boolean supportslimit () {return true;} public Boolean supportslimitoffset () {return true ;}} public class oracledialect extends dialect {Public String getpagesql (string SQL, int pagecurrent, int pagesize) {// original SQL string orgsql = SQL. trim (); // reset the current page pagecurrent = pagecurrent-1; // final SQL stringbuffer finalesql = new stringbuffer (); // if the current page is greater than 0 finalesql. append ("select * from (select row _. *, rownum _ from ("); // append the original SQL statement finalesql. append (orgsql); // if the current page is greater than 0 if (pagecurrent> 0) {finalesql. append (") Row _) where rownum _ <=" + (pagecurrent * pagesize) + "+" + pagesize) + "and rownum _>" + String. valueof (pagecurrent * pagesize);} else {// if the current page <= 0 finalesql. append (") Row _) where rownum _ <=" + String. valueof (pagesize);} return finalesql. tostring () ;} public Boolean supportslimit () {return true;} public Boolean supportslimitoffset () {return true ;}} public class systemmetaobject {public static final objectfactory default_object_factory = new defaultobjectfactory (); public static final objectwrapperfactory metadata = new defaultobjectwrapperfactory (); public static final metaobject null_meta_object = metaobject. forobject (nullobject. class, default_object_factory, default_object_wrapper_factory); Private systemmetaobject () {// prevent instantiation of static class} Private Static class nullobject {} public static metaobject foject (Object object) {return metaobject. forobject (object, default_object_factory, default_object_wrapper_factory );}}
<configuration> <properties> <property name="dialect" value="oracle" /> </properties> <settings> <setting name="lazyLoadingEnabled" value="true" /> <setting name="jdbcTypeForNull" value="VARCHAR" /> </settings> <plugins> <plugin interceptor="com.page.interceptor.PageInterceptor"> <property name="dialectClass" value="com..page.dialect.OracleDialect" /> </plugin> </plugins></configuration>
Implementation of mybatis paging plug-in