The role of configuration class in MyBatisThe configuration class holds configuration information for all MyBatis. That is to say, all configuration information in Mybaits-config.xml and Usermapper.xml can find the appropriate information in the Configruation object. Typically, MyBatis creates only one Configration object during the run, and the configuration information can no longer be modified. How to configure MyBatis can look at this document: http://mybatis.org/mybatis-3/zh/configuration.html
Properties of configurationThe attributes of configuration are mainly divided into two main parts: the configuration read from the Mybatis-config.xml from the Mapper configuration file or mapper annotation read the configuration of the two parts of the corresponding relationship between the properties and configuration
corresponding properties from the Mybatis-config.xml file
protected Boolean saferowboundsenabled = false;
Protected Boolean saferesulthandlerenabled = true;
protected Boolean mapunderscoretocamelcase = false;
Protected Boolean aggressivelazyloading = true;
Protected Boolean multipleresultsetsenabled = true;
protected Boolean Usegeneratedkeys = false;
Protected Boolean Usecolumnlabel = true;
Protected Boolean cacheenabled = true;
protected Boolean callsettersonnulls = false;
protected String Logprefix; Protected Class?
Extends log> Logimpl;
protected Localcachescope localcachescope = localcachescope.session;
protected Jdbctype jdbctypefornull = Jdbctype.other; protected set<string> lazyloadtriggermethods = new Hashset<string> (arrays.aslist (new string[] {"Equals", "
Clone "," Hashcode "," toString "}));
protected Integer defaultstatementtimeout;
protected Executortype defaultexecutortype = executortype.simple;
protected Automappingbehavior automappingbehavior = automappingbehavior.partial;Protected Properties Variables = new properties ();
protected Objectfactory objectfactory = new Defaultobjectfactory ();
protected Objectwrapperfactory objectwrapperfactory = new Defaultobjectwrapperfactory ();
protected Mapperregistry mapperregistry = new Mapperregistry (this);
protected Boolean lazyloadingenabled = false;
protected Proxyfactory proxyfactory;
Protected final Interceptorchain Interceptorchain = new Interceptorchain ();
Protected final Typehandlerregistry typehandlerregistry = new Typehandlerregistry ();
Protected final Typealiasregistry typealiasregistry = new Typealiasregistry (); Protected final Languagedriverregistry languageregistry = new Languagedriverregistry ();
The above properties can be said to have been read by the Mybatis-config.xml file. For example, the setting configuration in a file
<settings>
<setting name= "cacheenabled" value= "true"/> <setting name=
"lazyloadingenabled" Value= ' true '/>
<setting name= ' multipleresultsetsenabled ' value= ' true '/> <setting ' name= '
Usecolumnlabel "value=" true "/>
<setting name=" Usegeneratedkeys "value=" false "/> <setting name=
"Automappingbehavior" value= "PARTIAL"/>
<setting name= "Defaultexecutortype" value= "simple"/>
<setting name= "Defaultstatementtimeout value="/> <setting name= "
defaultfetchsize" value= "100" >
<setting name= "saferowboundsenabled" value= "false"/> <setting
"Name=" Mapunderscoretocamelcase "value=" false "/> <setting name=" Localcachescope "value=" session
"/>
<setting name= "Jdbctypefornull" value= "other"/> <setting name=
"Lazyloadtriggermethods" equals , clone,hashcode,tostring "/>
</settings>
Look at the contents of the configuration and the name of the property in the configuration, you probably know the corresponding relationship. Believe that after the content of the analysis will not be too complicated.
Properties read from the mapper configuration fileThe following properties are read from the mapper configuration file
Protected final map<string, mappedstatement> mappedstatements = new Strictmap<mappedstatement> ("Mapped Statements Collection ");
Protected final map<string, cache> caches = new Strictmap<cache> ("caches collection");
Protected final map<string, resultmap> resultmaps = new strictmap<resultmap> ("Result Maps collection");
Protected final map<string, parametermap> parametermaps = new Strictmap<parametermap> ("Parameter Maps Collection ");
Protected final map<string, keygenerator> keygenerators = new Strictmap<keygenerator> ("Key generators Collection ");
One of the most important and relatively complex is the following two (mapper configuration files are also primarily configured with these two items): The Mappedstatements property, which holds the Select/update/insert/delete node information in all mapper configuration files. The property type is a map,key sql corresponding id,mappedsatement is a Java object that holds a Select/update/insert/delete node information. The Resultmaps property, which holds the Resultmap node in all mapper configuration files. The mapper configuration file is also primarily configured with SELECT/UPDATE/INSERT/DELETE/RESULTMAP nodes.
Configuration Loading ProcessFor mybatis-config.xml configuration files and mapper configuration files, MyBatis is also resolved by two corresponding classes. Xmlconfigbuilder parsing mybatis-config.xml Configuration to Configuration Xmlmapperbuilder parsing mapper configuration file configuration into configuration
Xmlconfigbuilder.parse () method
To get configuration code through Sqlsessionfactory
Sqlsessionfactory sqlsessionfactory=new Sqlsessionfactorybuilder (). Build (IS);
System.out.println (Sqlsessionfactory.getconfiguration ());
Then look at the Sqlsessionfactorybuilder.build () method:
Public Sqlsessionfactory builds (InputStream inputstream) {return build (InputStream, NULL, NULL); Sqlsessionfactory Build (InputStream InputStream, String Environment) {return build (InputStream, Environme
NT, NULL); Sqlsessionfactory Build (InputStream InputStream, properties properties) {return build (InputStream, NULL,
properties);
Sqlsessionfactory Build (InputStream InputStream, String Environment, properties properties) {try {
Xmlconfigbuilder parser = new Xmlconfigbuilder (InputStream, Environment, properties);
It can be seen from here that Xmlconfigbuilder.parse () returns a configuration object return build (Parser.parse ());
catch (Exception e) {throw exceptionfactory.wrapexception ("Error building sqlsession.", e);
finally {errorcontext.instance (). reset ();
try {inputstream.close (); The catch (IOException e) {//intentionally ignore.
Prefer previous error. }} public Sqlsessionfactory build (Configuration config) {return new Defaultsqlsessionfactory (config); }
Load specific configuration
Public Configuration Parse () {if (parsed) {throw new Builderexception ("Each xmlconfigbuilder can only be used
Once. ");}
parsed = true;
Parseconfiguration (Parser.evalnode ("/configuration"));
return configuration; ///Load from XML configuration file to configuration object private void Parseconfiguration (XNode root) {try {//Load properties node, typically defined Some variable propertieselement (Root.evalnode ("Properties"));
Issue #117 Read Properties I//load alias Typealiaseselement (Root.evalnode ("typealiases"));
Interceptor Pluginelement (Root.evalnode ("plugins"));
Objectfactoryelement (Root.evalnode ("objectfactory"));
Objectwrapperfactoryelement (Root.evalnode ("objectwrapperfactory"));
Settingselement (Root.evalnode ("Settings")); Environmentselement (Root.evalnode ("Environments")); Read it after Objectfactory and objectwrapperfactory issue #631 databaseidproviderelement root.evalnode ("Database
Idprovider ")); Load the mapper configuration file, the most importantThere are two: one is the definition of SQL, one is Resultmap typehandlerelement (Root.evalnode ("typehandlers"));
Mapperelement (Root.evalnode ("mappers")); The catch (Exception e) {throw new Builderexception ("Error parsing SQL Mapper Configuration.
Cause: "+ E, E); }
}
Load Properties node
private void Propertieselement (XNode) throws Exception {if (context!= null) {//Load properties under Property child nodes first
Properties defaults = Context.getchildrenasproperties ();
String resource = Context.getstringattribute ("resource");
String url = context.getstringattribute ("url"); You cannot set both the Resource property and the URL property if (Resource!= null && URL!= null) {throw new Builderexception ("the Prop erties element cannot specify both a URL and a resource based property file reference.
Please specify one or the other. ");}
if (resource!= null) {//will overwrite the configuration of the child node Defaults.putall (resources.getresourceasproperties (Resource));
else if (URL!= null) {//will overwrite the configuration defaults.putall (resources.geturlasproperties (URL) of the child node);
Properties VARs = Configuration.getvariables ();
if (VARs!= null) {Defaults.putall (VARs);
} parser.setvariables (defaults); Set the list of variables to Configuration.setVariables (defaults); }
}
From this method you can see that the configuration rules can be set URL or resource property from the external file to load a properties file can be configured through the property child node, if the child node attribute key and external file key Repeat, the child node will be covered Programmatically defined attributes are finally loaded, with the highest precedence:
Public sqlsessionfactory Build (InputStream InputStream, properties properties)
Properties Configuration Sample
<properties resource= "Org/mybatis/example/config.properties" >
<property name= "username" value= "dev_" User "/>
<property name=" Password value= "F2fa3!33tyyg"/>
</properties>
The main load here is to use the following configuration as a variable!
Load alias
private void Typealiaseselement (xnode parent) {if (parent!= null) {for (XNode Child:parent.getChildren ()) { if ("Package". Equals (Child.getname ())) {//package way, rarely used, skip String typealiaspackage = Child
. Getstringattribute ("name");
Configuration.gettypealiasregistry (). registeraliases (Typealiaspackage);
else {String alias = Child.getstringattribute ("Alias");
String type = Child.getstringattribute ("type");
try {class<?> clazz = resources.classforname (type);
if (alias = = null) {Typealiasregistry.registeralias (clazz);
else {//load into alias Registry Typealiasregistry.registeralias (alias, Clazz); (ClassNotFoundException e) {throw new Builderexception ("Error registering Typealias for") "+ Alias +" '.
Cause: "+ E, E); }
}
}
}
}
Look again typealiasregistry source code, found that MyBatis has been defined a lot of aliases, easy to configure later
Public Typealiasregistry () {Registeralias ("string", String.class);
Registeralias ("byte", Byte.class);
Registeralias ("Long", long.class);
Registeralias ("short", short.class);
Registeralias ("int", integer.class);
Registeralias ("integer", Integer.class);
Registeralias ("Double", double.class);
Registeralias ("float", float.class);
Registeralias ("boolean", Boolean.class);
Registeralias ("byte[]", byte[].class);
Registeralias ("long[]", long[].class);
Registeralias ("short[]", short[].class);
Registeralias ("int[]", integer[].class);
Registeralias ("integer[]", integer[].class);
Registeralias ("double[]", double[].class);
Registeralias ("float[]", float[].class);
Registeralias ("boolean[]", boolean[].class);
Registeralias ("_byte", Byte.class);
Registeralias ("_long", Long.class);
Registeralias ("_short", Short.class);
Registeralias ("_int", Int.class);
Registeralias ("_integer", Int.class); Registeralias ("_douBle ", double.class);
Registeralias ("_float", Float.class);
Registeralias ("_boolean", Boolean.class);
Registeralias ("_byte[]", byte[].class);
Registeralias ("_long[]", long[].class);
Registeralias ("_short[]", short[].class);
Registeralias ("_int[]", int[].class);
Registeralias ("_integer[]", int[].class);
Registeralias ("_double[]", double[].class);
Registeralias ("_float[]", float[].class);
Registeralias ("_boolean[]", boolean[].class);
Registeralias ("date", Date.class);
Registeralias ("decimal", bigdecimal.class);
Registeralias ("BigDecimal", Bigdecimal.class);
Registeralias ("BigInteger", Biginteger.class);
Registeralias ("Object", Object.class);
Registeralias ("date[]", date[].class);
Registeralias ("decimal[]", bigdecimal[].class);
Registeralias ("bigdecimal[]", bigdecimal[].class);
Registeralias ("biginteger[]", biginteger[].class);
Registeralias ("object[]", object[].class);
Registeralias ("Map", Map.class); Registeralias ("HashMap", Hashmap.class);
Registeralias ("list", List.class);
Registeralias ("ArrayList", Arraylist.class);
Registeralias ("collection", Collection.class);
Registeralias ("iterator", iterator.class);
Registeralias ("ResultSet", Resultset.class); }
There is also a way to load class by using an alias
Public <T> class<t> Resolvealias (String string) {
try {
if (string = = null) return null;
String key = String.tolowercase (Locale.english); Issue #748
class<t> value;
if (Type_aliases.containskey (key)) {
//if it is an alias, return
value = (class<t>) type_aliases.get (key) directly from the registry;
} else {
value = (class<t>) resources.classforname (string);
}
return value;
} catch (ClassNotFoundException e) {
throw new typeexception ("could not resolve type alias" + String + "". ) Cause: "+ E, E);
}
}
Load Mapper configuration file
private void Mapperelement (xnode parent) throws Exception {if (parent!= null) {for (XNode Child:parent.get Children ()) {if ("package". Equals (Child.getname ())) {String mapperpackage = Child.getstringattribute ("
Name ");
Configuration.addmappers (Mapperpackage);
else {String resource = Child.getstringattribute ("resource");
String url = child.getstringattribute ("url");
String Mapperclass = Child.getstringattribute ("class"); if (resource!= null && URL = null && Mapperclass = null) {errorcontext.instance (). Resource
(Resource);
InputStream InputStream = resources.getresourceasstream (Resource); Xmlmapperbuilder mapperparser = new Xmlmapperbuilder (inputstream, configuration, res, parsed by Xmlmapperbuilder object)
Ource, Configuration.getsqlfragments ());
Mapperparser.parse (); else if (resource = null && URL!= null && Mapperclass = = null) {errorcontext.instance (). resource (URL);
InputStream inputstream = resources.geturlasstream (URL); Load Xmlmapperbuilder mapperparser = new Xmlmapperbuilder (inputstream, configuration, URL, Xmlmapperbuilder object resolution)
, configuration.getsqlfragments ());
Mapperparser.parse (); else if (resource = = null && URL = null && mapperclass!= null) {class<?> Mapperinte
Rface = Resources.classforname (Mapperclass);
Configuration.addmapper (Mapperinterface); else {throw new Builderexception ("A mapper element may only specify A URL, resource or class, but no more than one. ");}}}}
A mapper configuration file is eventually loaded into the configuration object by Xmlmapperbuilder object resolution. The parsing process of Xmlmapperbuilder is similar to Xmlconfigbuilder parsing process, and then analyzed in detail later.
load Other configuration items There are some configuration items not mentioned here, such as: Plug-in/Interceptor, object factory, setting items. These loading are relatively simple, as long as the heart can be seen to understand. In the future analysis of the code process, you will certainly see the configuration here, and then further study, but you can be sure that the configuration in many cases are using the default value.