The usage and principle analysis of Mapper mapping configuration in Java MyBatis framework _java

Source: Internet
Author: User

Built-in methods for Mapper
the model layer is the entity class, which corresponds to the database table. The controller layer is the servlet, mainly responsible for the business module Process Control, call the service interface method, in Struts2 is action. The service layer mainly makes the logical judgment, the DAO layer is the data access layer, docking with the database. As for Mapper is Mybtis framework mapping used, mapper mapping file is used in the DAO layer.

Here's a built-in way to introduce mapper:

1, countbyexample ===> query quantity according to the condition

int Countbyexample (userexample example);
 
Below is a complete list of
userexample example = new Userexample ();
 Criteria criteria = Example.createcriteria ();
 Criteria.andusernameequalto ("Joe");
 int count = Userdao.countbyexample (example);

Equivalent: SELECT COUNT (*) from user where username= ' Joe '

2, Deletebyexample ===> according to the conditions to delete more than one

int Deletebyexample (accountexample example);
 
The following is a complete case
userexample example = new Userexample ();
 Criteria criteria = Example.createcriteria ();
 Criteria.andusernameequalto ("Joe");
 Userdao.deletebyexample (example);
 Equivalent to: Delete from user where username= ' Joe '

3, deletebyprimarykey===> according to the conditions to delete a single

int Deletebyprimarykey (Integer ID);

Equivalent:

Delete from user where id=101
 

4, insert===> Insert data

int Insert (Account record);
 
The following is the complete case
User user = new user ();
 User.setid ();
 User.setusername ("test");
 User.setpassword ("123456")
 user.setemail ("674531003@qq.com");
 Userdao.insert (user);

Equivalent:

Insert into user values (Id,username,password,email, ' Test ', ' 123456 ', ' 674531003@qq.com ');

5, insertselective===> insert Data

int insertselective (Account record);

6, selectbyexample===> query data according to the condition

List<account> Selectbyexample (accountexample example);
 
The following is a complete case
userexample example = new Userexample ();
Criteria criteria = Example.createcriteria ();
Criteria.andusernameequalto ("Joe");
Criteria.andusernameisnull ();
Example.setorderbyclause ("username asc,email desc");
List<?>list = Userdao.selectbyexample (example);
Equivalent to: SELECT * from user where username = ' Joe ' and username are null ORDER by username Asc,email desc
 
//Note: Files generated in Ibator Userexample.java contains a static inner class Criteria, there are many methods in the Criteria, mainly defining the query conditions after the SQL statement where.

7, selectbyprimarykey===> based on the primary key query data

Account Selectbyprimarykey (Integer ID)//is equivalent to select * from user where id = variable ID


8. updatebyexampleselective===> to update fields with values that are not NULL by condition

int updatebyexampleselective (@Param ("record") the Account record, @Param ("example") accountexample example);
 
Below is a complete list of
userexample example = new Userexample ();
 Criteria criteria = Example.createcriteria ();
 Criteria.andusernameequalto ("Joe");
 User user = new user ();
 User.setpassword ("123");
 Userdao.updatebyprimarykeyselective (user,example);
 Equivalent to: Update user set password= ' 123 ' where username= ' Joe '


9, updatebyexampleselective===> update by condition

int Updatebyexample (@Param ("record") the Account record, @Param ("example") accountexample example);

10, updatebyprimarykeyselective===> Update by condition

int updatebyprimarykeyselective (Account record);

The following is a complete case of

 user user = new user ();
User.setid ();
User.setpassword ("Joe");
Userdao.updatebyprimarykeyselective (user);

Equivalent:

Update user set password= ' Joe ' where id=101
int updatebyprimarykeyselective (Account record);
 
The following is a complete case of
 
 user user = new user ();
User.setid ();
User.setpassword ("Joe");
Userdao.updatebyprimarykeyselective (user);

Equivalent to: Update user set password= ' Joe ' where id=101

11, updatebyprimarykey===> by the primary key update

int Updatebyprimarykey (Account record);

The following is a complete case of
user User =new User ();
 User.setid ();
 User.setusername ("Joe");
 User.setpassword ("Joe");
 User.setemail ("joe@163.com");
 Userdao.updatebyprimarykey (user);

Equivalent:

Update user set Username= ' Joe ', password= ' Joe ', email= ' joe@163.com ' where id=101
int Updatebyprimarykey (Account record);
 
The following is a complete case of
user User =new User ();
 User.setid ();
 User.setusername ("Joe");
 User.setpassword ("Joe");
 User.setemail ("joe@163.com");
 Userdao.updatebyprimarykey (user);

Equivalent:

Update user set Username= ' Joe ', password= ' Joe ', email= ' joe@163.com ' where id=101


Parsing a mapper XML configuration file
Let's see how MyBatis reads the Mapper XML configuration file and parses the SQL statements.

We remember this configuration of sqlsessionfactory:

<bean id= "Sqlsessionfactory" class= "Org.mybatis.spring.SqlSessionFactoryBean" >   
  <property name= " DataSource "ref=" DataSource "/> <property name=" configlocation "value="  
  classpath:configuration.xml "> </property>   
  <property name= "mapperlocations" value= "Classpath:com/xxx/mybatis/mapper/*.xml"/>   
  <property name= "typealiasespackage" value= "Com.tiantian.mybatis.model"/>   
</bean>  

This is configured with an Mapperlocations property, which is an expression Sqlsessionfactory will read all the XML format files below the package com.xxx.mybaits.mapper based on this expression, so how do you read the configuration file based on this attribute?

The answer is in the Buildsqlsessionfactory method in the Sqlsessionfactorybean class:

if (!isempty (this.mapperlocations)) {for 
   (Resource mapperLocation:this.mapperLocations) { 
    if ( Mapperlocation = = null) { 
     continue 
    } 
 
    try { 
     Xmlmapperbuilder xmlmapperbuilder = new Xmlmapperbuilder (Mapperlocation.getinputstream (), 
       Configuration, Mapperlocation.tostring (), configuration.getsqlfragments ()); 
     Xmlmapperbuilder.parse (); 
    } catch (Exception e) { 
     throw new Nestedioexception ("Failed to parse Mapping resource: '" + mapperlocation + "'", e); 
   } finally { 
     errorcontext.instance (). reset (); 
 
    if (logger.isdebugenabled ()) { 
     logger.debug ("Parsed mapper file: ' + mapperlocation +" ');}} 
   } 
   

MyBatis uses an instance of the Xmlmapperbuilder class to resolve the mapper configuration file.

Public Xmlmapperbuilder (Reader reader, Configuration Configuration, String resource, map<string, xnode> sqlfragments) {This 
  (new Xpathparser (reader, True, Configuration.getvariables (), New Xmlmapperentityresolver ()), 
    configuration, resource, sqlfragments); 

Private Xmlmapperbuilder (Xpathparser parser, Configuration Configuration, String resource, map<string, xnode> sqlfragments) { 
  super (configuration); 
  This.builderassistant = new Mapperbuilderassistant (configuration, Resource); 
  This.parser = parser; 
  this.sqlfragments = sqlfragments; 
  This.resource = resource; 
 } 

Then the system calls the Xmlmapperbuilder parse method to parse the mapper.

public void Parse () { 
  //If the configuration object has not yet loaded the XML configuration file (to avoid duplicate loading, it is actually a confirmation that the attributes and contents of the Mapper node are parsed, or that the 
  child nodes of it are parsed such as cache, SQL, select, Resultmap, Parametermap, etc.), the 
  //then resolves the mapper node from the input stream and then resets the resource state to the loaded 
  if (! Configuration.isresourceloaded (Resource)) { 
   configurationelement (Parser.evalnode ("/mapper")); 
   Configuration.addloadedresource (Resource); 
   Bindmapperfornamespace (); 
  } 
  Resolves the <resultMap> node parsependingresultmaps that the parent object to which the extends property points to is not yet processed when processing resultmap in the ConfigurationElement function 
  ( ); 
  Resolves a <cache> node that does not exist when processing cache-ref in the ConfigurationElement function (this occurs if Cache-ref is loaded before the cache node to which it points) 
  Parsependingchacherefs (); 
  Ditto, if the cache does not load words when processing statement will also throw an exception 
  parsependingstatements (); 
 } 

The process of MyBatis parsing mapper XML files is already obvious, and then we'll see how it resolves mapper:

private void ConfigurationElement (XNode context) {try {//Get Mapper Node Namespace property String Namespace = Context.g 
   Etstringattribute ("namespace"); 
   if (Namespace.equals ("")) {throw new Builderexception ("Mapper ' namespace cannot be empty"); 
   //Set the current namespace Builderassistant.setcurrentnamespace (namespace); 
   Analytic mapper <cache-ref> node cacherefelement (Context.evalnode ("Cache-ref")); 
   Parsing mapper <cache> node cacheelement (context.evalnode ("cache"); 
   Analytic mapper <parameterMap> node parametermapelement (context.evalnodes ("/mapper/parametermap")); 
   Analytic mapper <resultMap> node resultmapelements (context.evalnodes ("/mapper/resultmap")); 
   Analytic mapper <sql> node sqlelement (context.evalnodes ("/mapper/sql")); Use Xmlstatementbuilder objects to parse mapper <select>, <insert>, <update>, <delete> nodes,// Mybaits uses the Mappedstatement.builder class to build a Mappedstatement object,/So a SQL in mybaits corresponds to a mappedstatement buildStatementfromcontext (Context.evalnodes ("Select|insert|update|delete")); The catch (Exception e) {throw new Builderexception ("Error parsing Mapper XML. 
  Cause: "+ E, E); 

 } 
 }

The

configurationelement function almost resolves all the child nodes under the Mapper node, so mybaits resolves all the nodes in mapper. It is added to the configuration object for Sqlsessionfactory objects to be used at any time. Here we need to add a little bit about how Mybaits uses the Parsestatementnode function of the object of the Xmlstatementbuilder class to borrow Mapperbuilderassistant class object Builderassistant addmappeds tatement resolves Mappedstatement and associates it to a configuration class object:

public void Parsestatementnode () {//id property String id = context.getstringattribute ("id"); 
 
  DatabaseId Property String databaseId = Context.getstringattribute ("DatabaseId"); 
  if (!databaseidmatchescurrent (ID, databaseId, This.requireddatabaseid)) {return; 
  //fetchsize attribute Integer fetchsize = Context.getintattribute ("Fetchsize"); 
  Timeout attribute Integer timeout = context.getintattribute ("timeout"); 
  Parametermap Property String Parametermap = Context.getstringattribute ("Parametermap"); 
  ParameterType property String parametertype = Context.getstringattribute ("ParameterType"); 
  class<?> Parametertypeclass = Resolveclass (parametertype); 
  Resultmap Property String Resultmap = Context.getstringattribute ("Resultmap"); 
  Resulttype Property String Resulttype = Context.getstringattribute ("Resulttype"); 
  Lang attribute String lang = context.getstringattribute ("lang"); 
 
  Languagedriver langdriver = getlanguagedriver (lang); class<?> Resulttypeclass = ResolVeclass (Resulttype); 
  ResultsetType Property String ResultsetType = Context.getstringattribute ("ResultsetType"); StatementType StatementType = statementtype.valueof (Context.getstringattribute ("StatementType"), 
  StatementType.PREPARED.toString ())); 
 
  ResultsetType resultsettypeenum = Resolveresultsettype (ResultsetType); 
  String nodename = Context.getnode (). Getnodename (); 
  Sqlcommandtype Sqlcommandtype = sqlcommandtype.valueof (Nodename.touppercase (locale.english)); 
  is <select> node Boolean isselect = Sqlcommandtype = = Sqlcommandtype.select; 
  Flushcache attribute Boolean flushcache = Context.getbooleanattribute ("Flushcache",!isselect); 
  UseCache attribute Boolean usecache = Context.getbooleanattribute ("UseCache", isselect); 
 
  Resultordered Property Boolean resultordered = Context.getbooleanattribute ("resultordered", false); Include fragments before parsing xmlincludetransformer includeparser = new Xmlincludetransformer (Configuration, Buil 
  Derassistant); IncluDeparser.applyincludes (Context.getnode ()); 
  Parse Selectkey after includes and remove them. 
   
  Processselectkeynodes (ID, Parametertypeclass, langdriver); Parse the SQL (pre: <selectKey> and <include> were parsed and removed) sqlsource Sqlsource = Langdriver. 
  Createsqlsource (configuration, context, parametertypeclass); 
  ResultSets property String resultsets = Context.getstringattribute ("resultsets"); 
  Keyproperty Property String Keyproperty = Context.getstringattribute ("Keyproperty"); 
  KeyColumn Property String KeyColumn = Context.getstringattribute ("KeyColumn"); 
  Keygenerator Keygenerator; 
  String Keystatementid = id + selectkeygenerator.select_key_suffix; 
  Keystatementid = Builderassistant.applycurrentnamespace (Keystatementid, true); 
  if (Configuration.haskeygenerator (Keystatementid)) {keygenerator = Configuration.getkeygenerator (keyStatementId); else {//usegeneratedkeys Property Keygenerator = Context.getbooleanattribute ("UsegenerateDkeys ", Configuration.isusegeneratedkeys () && SqlCommandType.INSERT.equals (sqlcommandtype))? 
  New Jdbc3keygenerator (): New Nokeygenerator (); Builderassistant.addmappedstatement (IDs, Sqlsource, StatementType, Sqlcommandtype, fetchsize, timeout, paramete RMap, Parametertypeclass, Resultmap, Resulttypeclass, Resultsettypeenum, Flushcache, UseCache, resultOrdered, K 
 Eygenerator, Keyproperty, KeyColumn, DatabaseId, Langdriver, resultsets); 

 }

The above code shows that Mybaits uses XPath to parse Mapper's configuration file to include Resultmap, Parametermap, Cache, Statement nodes use the associated builder to create and associate the resulting object to the configuration object, which can be obtained from the sqlsession. This explains the problem of how we mybaits get to the mapper and execute the SQL statements when we use sqlsession to manipulate the database.

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.