Objective
When the business interface in the system needs to call MyBatis's SQL, the parameters defined by the business interface do not conform to MyBatis's own internal specifications, then the parameters of the business interface need to be converted into MyBatis internal parameter gauges, and the Mapperproxy agent completes this duty. Here's a look at the analysis.
Public object invoke (Object proxy, method method, object[] args) throws throwable { if (Object.class.equals (Method.getdeclaringclass ())) { try { return method.invoke (This, args); } catch (Throwable t) { throw exceptionutil.unwrapthrowable (t); } } final MapperMethod Mappermethod = cachedmappermethod (method); return mappermethod.execute ( Sqlsession, args);} Private mappermethod cachedmappermethod (Method method) { Mappermethod mappermethod = methodcache.get (method); if ( Mappermethod ==&nbSp;null) { mappermethod = new mappermethod ( Mapperinterface, method, sqlsession.getconfiguration ()); Methodcache.put (Method, mappermethod); } return Mappermethod;}
The above invoke is the proxy class callback method, and the Cachedmappermethod method does a cache. Here the constructor of the Mappermethod class and the Execute method of the Mappermethod class are the main logic, first look at the Mappermethod constructor.
1 Mappermethod Constructors
There are 2 classes instantiated, and the 2 classes are analyzed according to the query in the diagram.
Public sqlcommand (Configuration configuration, class<?> mapperinterface, method method) throws BindingException { // cn.vansky.schedule.time.menu.dao.menumapper.findmenubyuserid string Statementname = mapperinterface.getname () + "." + method.getname (); mappedstatement ms = null; if (Configuration.hasstatement (statementname)) { ms = configuration.getmappedstatement (StatementName); } else if (!mapperinterface.equals (Method.getdeclaringclass). GetName ()) { // issue #35 String Parentstatementname = method.getdeclaringclass (). GetName () + "." &nBsp;+ method.getname (); if ( Configuration.hasstatement (parentstatementname)) { ms = configuration.getmappedstatement (Parentstatementname); } } if (ms = = null) { throw new bindingexception (" invalid bound statement (Not found): " + statementname); } // cn.vansky.schedule.time.menu.dao.menumapper.findmenubyuserid name = ms.getid (); // select type = ms.getsqlcommandtype (); if (Type == SQlcommandtype.unknown) { throw new Bindingexception ("unknown execution method for: " + name); }}public methodsignature (Configuration configuration, method method) throws BindingException { // return value type class // interface java.util.List This.returntype = method.getreturntype (); // has no return value true : None, False: // false This.returnsvoid = void.class.equals (This.returntype); // Whether the return type is a collection collection or an array // true this.returnsmany = (Configuration.getobjectfactory (). IsCOllection (this.returntype) | | this.returntype.isarray ()); // return type is map, get annotations mapkey // above method call with a value of null this.mapkey = Getmapkey (method); // whether the return type is map // false this.returnsMap = (This.mapkey != null); The // parameter has @param annotations // true this.hasnamedparameters = hasnamedparams (method); // null this.rowBoundsIndex = Getuniqueparamindex (Method, rowbounds.class); // null this.resulthandlerindex = getuniqueparamindex (method, Resulthandler.class); // get parameter list // 0 -> userId this.params = Collections.unmodifiablesortedmap (Getparams (Method, this.hasnamedparameters));}
The SqlCommand class gets the unique identity of the processing and the SQL statement type, and the Methodsignature class handles the entry type and the parameter type of the business interface method.
2 mappermethed Execution entry-->execute method
Public object execute (Sqlsession sqlsession, object[] args) { Object result; if (Sqlcommandtype.insert == command.gettype () ) { // New object param = method.convertargstosqlcommandparam (args); result = Rowcountresult (Sqlsession.insert (Command.getname (), param)); } else if (Sqlcommandtype.update == command.gettype ()) { // Modify object param = method.convertargstosqlcommandparam ( args); result = rowcountresult (Sqlsession.update (Command.getName ( ); } else if (sqlcommandtype.delete == , param)) Command.gettype ()) { // Delete Object param = Method.convertargstosqlcommandparam (args); result = Rowcountresult (Sqlsession.delete (Command.getname (), param)); } else if (Sqlcommandtype.select == command.gettype ()) { // Inquiries if (method.returnsvoid () && Method.hasresulthandler ()) { // no return value void executewithresulthandler (Sqlsession, args); result = null; } else if ( Method.returnsmany ()) { // set collection or array result =&Nbsp;executeformany (Sqlsession, args); } else if ( Method.returnsmap ()) { // Map result = executeformap (Sqlsession, args); } else { // Unique Results object param = method.convertargstosqlcommandparam (args); result = sqlsession.selectone (Command.getName (), param); } } else { throw new bindingexception ("unknown execution method for: " + Command.getname ()); } if (result == null && method.getreTurntype (). Isprimitive () && !method.returnsvoid ()) { throw new bindingexception ("mapper method " " + command.getname () + " attempted to return null from a method with a primitive return type (" + Method.getreturntype () + ")."); } return result;}
Add (INSERT), change (UPDATE), delete (delete), these 3 kinds of operations can be summed up as one, first, the actual entry of the business interface into the MyBatis internal parameters, and then call the Sqlsession processing method, the results are processed, and return the results.
Check (SELECT) has 4 cases.
One: no return value
Two: Return is a collection of collection or arrays
Three: Return is map
Four: Returns a result
Details of 4 cases are no longer analyzed.
Summarize
First of all, we need to turn the actual import parameters of the business interface into the MyBatis internal parameter, then call the sqlsession corresponding processing method, and finally processing the return result, return to the business interface.
A proxy class that connects MyBatis internal sqlsession with the business interface Mapperproxy