MyBatis Series (10)---SQL Execution process analysis (source code) (GO)

Source: Internet
Author: User
Tags stmt throwable

Reprinted from: http://www.cnblogs.com/dongying/p/4142476.html

1. Sqlsessionfactory and sqlsession.

Through the previous chapters on the introduction and use of mybatis, everyone can appreciate the importance of sqlsession, yes, on the surface, we are all through the sqlsession to execute the SQL statement (note: From the surface, the actual will be said later). So let's start by looking at how to get sqlsession:

(1) First, sqlsessionfactorybuilder to read the MyBatis configuration file and build a defaultsqlsessionfactory. The source code is as follows:

/**   * A series of construction methods will eventually call this method (this method is called when the configuration file is reader, and a InputStream method corresponds to this)   * @param reader   * @param environment   * @param Properties   * @return   *  /public sqlsessionfactory build (reader Reader, String Environment, Properties properties) {    try {      ///through Xmlconfigbuilder parsing configuration file, resolved configuration related information will be encapsulated as a single Configuration object      Xmlconfigbuilder parser = new Xmlconfigbuilder (reader, Environment, properties);      This creates the Defaultsessionfactory object      return Build (Parser.parse ());    } catch (Exception e) {      throw Exceptionfactory.wrapexception ("Error building sqlsession.", E);    } finally {      errorcontext.instance (). reset ();      try {        reader.close ();      } catch (IOException e) {        //intentionally ignore. Prefer previous error.}}  }  Public sqlsessionfactory build (Configuration config) {    return new defaultsqlsessionfactory (config);  }

(2) When we get to sqlsessionfactory, we can get the Sqlsession object through Sqlsessionfactory. The source code is as follows:

/** * Usually a series of opensession methods will eventually call this method * @param exectype * @param level * @param autocommit * @return */private Sqlsession Opensessionfromdatasource (Executortype exectype, Transactionisolationlevel level, Boolean autoCommit) {Tra    Nsaction tx = NULL; try {//Confuguration object to get MyBatis-related configuration information, environment object contains data source and transaction configuration final environment environment = Configurati      On.getenvironment ();      Final Transactionfactory transactionfactory = gettransactionfactoryfromenvironment (Environment);      tx = Transactionfactory.newtransaction (Environment.getdatasource (), level, autocommit); Previously said, from the surface, we are using sqlsession in the execution of the SQL statement, actually, is actually executed through Excutor, Excutor is for statement package final Executor Executor = Configurat      Ion.newexecutor (TX, exectype);    Key look here, create a Defaultsqlsession object return new defaultsqlsession (configuration, executor, autocommit); } catch (Exception e) {closetransaction (TX);//May has fetched a connection so lets call close () throw Except IonFactory.wrapexception ("Error opening session.    Cause: "+ E, E);    } finally {errorcontext.instance (). reset (); }  }

Through the above steps, we have already got the Sqlsession object. The next thing to do is what to do (and, of course, execute the SQL statement). Look at the above, we also recall the previous written demo,

Sqlsessionfactory sessionfactory = null;  String resource = "Mybatis-conf.xml";  try {     //sqlsessionfactorybuilder read config file    sessionfactory = new Sqlsessionfactorybuilder (). Build (Resources                . Getresourceasreader (Resource));} catch (IOException e) {      e.printstacktrace ();  }    
Get sqlsession through Sqlsessionfactory
Sqlsession sqlsession = Sessionfactory.opensession ();

It's a real thing, isn't it?

Sqlsession we've got it, we can call sqlsession in a series of select ..., insert ..., update ..., delete ... method to make CRUD operations easy and effortless. That's it?  So where's the mapping file we've been configuring? Don't worry, let's keep looking down:

2. Mapperproxy of Sharp Weapon:

In MyBatis, through the mapperproxy dynamic agent of our DAO, that is, when we execute their own written DAO inside the method, is actually the corresponding mapperproxy in the agent. So, let's see how to get the Mapperproxy object:

(1) obtained from the configuration by sqlsession. The source code is as follows:

/**   * Do nothing, go directly to the configuration to find, brother is so capricious   * *  @Override public  <T> T Getmapper (class<t> Type) {    return Configuration.<t>getmapper (type, this);  }

(2) Sqlsession the burden to the configuration, then look at the configuration. The source code is as follows:

/**   * Hot potato, I do not, you find mapperregistry to be   * @param type   * @param sqlsession   * @return  * * Public <T> T Getmapper (class<t> type, sqlsession sqlsession) {    return mapperregistry.getmapper (type, sqlsession);  }

(3) configuration do not this hot potato, and then dumped to the mapperregistry, then we look at Mapperregistry. The source code is as follows:

/**   * The net let me do, no, there is no one, I don't do who do   * @param type   * @param sqlsession   * @return  * * Suppresswarnings ("unchecked") public  <T> T getmapper (class<t> type, sqlsession sqlsession) {    // Can lazy on lazy, I put the menial hand to Mapperproxyfactory to do    final mapperproxyfactory<t> mapperproxyfactory = (mapperproxyfactory <T>) Knownmappers.get (type);    if (mapperproxyfactory = = null) {      throw new Bindingexception ("type" + Type + "is isn't known to the Mapperregistry.") );    }    try {      //key here      return Mapperproxyfactory.newinstance (sqlsession)    } catch (Exception e) {      throw New Bindingexception ("Error getting mapper instance. Cause: "+ E, E);    }  }

(4) Mapperproxyfactory was a bitter B man, and the menial work was finally given to him. Let's look at the source code:

/**   * Others abuse me times, I treat others as a love   * @param mapperproxy   * @return * * * *  @SuppressWarnings ("unchecked")  Protected T newinstance (mapperproxy<t> mapperproxy) {    //dynamic Proxy We write the DAO interface    return (T) Proxy.newproxyinstance (Mapperinterface.getclassloader (), new class[] {mapperinterface}, Mapperproxy);  }    Public T newinstance (sqlsession sqlsession) {    final mapperproxy<t> mapperproxy = new Mapperproxy<t> ( Sqlsession, Mapperinterface, Methodcache);    Return newinstance (Mapperproxy);  }

With the above dynamic agent, we can easily use the DAO interface, as we have written before the demo:

Userdao usermapper = Sqlsession.getmapper (userdao.class);   User Insertuser = new user ();

This is more convenient, oh, looks like the source of MyBatis is such a thing ah.

Don't worry, it's not over yet, we haven't seen how the SQL statements are executed.

3. Excutor:

Next, we have to really see the SQL implementation process.

Above, we get the mapperproxy, each mapperproxy corresponds to a DAO interface, then when we use, how does Mapperproxy do? The Source:

Mapperproxy:

/**   * Mapperproxy will trigger this method on execution *  /@Override Public  object Invoke (Object proxy, 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);    Apart, mainly to mappermethod himself to tube    return Mappermethod.execute (sqlsession, args);  }

Mappermethod:

View Code

Now that we have returned to sqlsession, then we will look at the sqlsession crud method, in order to save trouble, or choose one of the methods to do analysis. Here, we chose the SelectList method:

Public <E> list<e> SelectList (String statement, Object parameter, rowbounds rowbounds) {    try {      Mappedstatement ms = Configuration.getmappedstatement (statement);      Crud is actually handed to Excetor to deal with, Excutor actually just wear a vest only, sample, don't think wear a vest I don't know you!      return Executor.query (MS, wrapcollection (parameter), rowbounds, Executor.no_result_handler);    } catch (Exception e) {      throw exceptionfactory.wrapexception ("Error querying database.  Cause: "+ E, E);    } finally {      errorcontext.instance (). reset ();    }  }

Then, through a layer of calls, will eventually come to the Doquery method, here we will find a excutor to see the implementation of Doquery method, I have chosen simpleexecutor:

Public <E> list<e> Doquery (mappedstatement MS, Object parameter, rowbounds rowbounds, Resulthandler Resulthandler, Boundsql boundsql) throws SQLException {    Statement stmt = null;    Try {      Configuration configuration = Ms.getconfiguration ();      Statementhandler handler = Configuration.newstatementhandler (wrapper, MS, parameter, Rowbounds, Resulthandler, BOUNDSQL);      stmt = Preparestatement (Handler, Ms.getstatementlog ());      Statementhandler encapsulates the statement, allowing Statementhandler to process      return Handler.<e>query (stmt, Resulthandler);    } finally {      closestatement (stmt);    }  }

Next, let's look at an implementation class Preparedstatementhandler for Statementhandler (which is also our most common, encapsulated preparedstatement) and see how it's handled:

Public <E> list<e> Query (Statement Statement, Resulthandler resulthandler) throws SQLException {     //to this, True Colors, PreparedStatement, this everyone has memorized    preparedstatement PS = (preparedstatement) statement;    Ps.execute ();    The result was given to Resultsethandler to process    return resultsethandler.<e> handleresultsets (PS);  }

At this time, the execution process of SQL is finished. I'm only here to suggest that interested to see the source of Mybatis3.

Well, this is the end of this time, recently too busy, and should be busy.

MyBatis Series (10)---SQL Execution process analysis (source code) (GO)

Related Article

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.