<!--

       Copyright ${license.git.copyrightYears} the original author or authors.

       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
       You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.

-->
﻿<?xml version="1.0" encoding="UTF-8"?>
<!--

       Copyright 2009-2019 the original author or authors.

       Licensed under the Apache License, Version 2.0 (the "License");
       you may not use this file except in compliance with the License.
       You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing, software
       distributed under the License is distributed on an "AS IS" BASIS,
       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific language governing permissions and
       limitations under the License.

-->
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">

  <properties>
    <title>MyBatis 3 | Configuration</title>
    <author email="clinton.begin@gmail.com">Clinton Begin</author>
  </properties>

  <body>
    <section name="Configuration">
      <p>
        The MyBatis configuration contains settings and
        properties
        that have a dramatic effect on how MyBatis behaves. The
        high level
        structure of the document is as follows:
      </p>

      <ul>
        <li>
          configuration
          <ul>
            <li><a href="#properties">properties</a></li>
            <li><a href="#settings">settings</a></li>
            <li><a href="#typeAliases">typeAliases</a></li>
            <li><a href="#typeHandlers">typeHandlers</a></li>
            <li><a href="#objectFactory">objectFactory</a></li>
            <li><a href="#plugins">plugins</a></li>
            <li><a href="#environments">environments</a>
              <ul>
                <li>
                  environment
                  <ul>
                    <li>transactionManager</li>
                    <li>dataSource</li>
                  </ul>
                </li>
              </ul>
            </li>
            <li><a href="#databaseIdProvider">databaseIdProvider</a></li>
            <li><a href="#mappers">mappers</a></li>
          </ul>
        </li>
      </ul>
      <subsection name="properties">
        <p>
          These are externalizable, substitutable properties that can be
          configured in a typical Java Properties file instance, or passed in
          through sub-elements of the properties element. For example:
        </p>
        <source><![CDATA[<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</properties>]]></source>
        <p>The properties can then be used throughout the configuration
          files
          to substitute values that need to be dynamically configured.
          For
          example:
        </p>
        <source><![CDATA[<dataSource type="POOLED">
  <property name="driver" value="${driver}"/>
  <property name="url" value="${url}"/>
  <property name="username" value="${username}"/>
  <property name="password" value="${password}"/>
</dataSource>]]></source>
        <p>
          The username and password in this example will be replaced by the
          values set in the properties elements. The driver and url
          properties
          would be replaced with values contained from the
          config.properties
          file. This provides a lot of options for
          configuration.
        </p>
        <p>
          Properties can also be passed into the SqlSessionFactoryBuilder.build()
          methods. For
          example:
        </p>
        <source><![CDATA[SqlSessionFactory factory =
  sqlSessionFactoryBuilder.build(reader, props);

// ... or ...

SqlSessionFactory factory =
  new SqlSessionFactoryBuilder.build(reader, environment, props);
]]></source>
        <p>
          If a property exists in more than one of these places, MyBatis
          loads
          them in the following order:
        </p>
        <ul>
          <li>Properties specified in the body of the properties element are
            read first,
          </li>
          <li>Properties loaded from the classpath resource or url attributes
            of the properties element are read second, and override any
            duplicate properties already specified,
          </li>
          <li>Properties passed as a method parameter are read last, and
            override any duplicate properties that may have been loaded from
            the properties body and the resource/url attributes.
          </li>
        </ul>
        <p>
          Thus, the highest priority properties are those passed in as a
          method
          parameter, followed by resource/url attributes and finally
          the
          properties specified in the body of the properties element.
        </p>

        <p>
          Since the MyBatis 3.4.2, your can specify a default value into placeholder as follow:
        </p>
        <source><![CDATA[
<dataSource type="POOLED">
  <!-- ... -->
  <property name="username" value="${username:ut_user}"/> <!-- If 'username' property not present, username become 'ut_user' -->
</dataSource>]]></source>

        <p>
          This feature is disabled by default. If you specify a default value into placeholder,
          you should be enable this feature by adding a special property as follow:
        </p>

        <source><![CDATA[
<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/> <!-- Enable this feature -->
</properties>]]></source>

        <p>
          <span class="label important">NOTE</span> Also If you are used already the <code>":"</code> as property key(e.g. <code>db:username</code>)
          or you are used already the ternary operator of OGNL expression(e.g. <code>${tableName != null ? tableName : 'global_constants'}</code>) on your sql definition,
          you should be change the character that separate key and default value by adding a special property as follow:
        </p>

        <source><![CDATA[
<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <property name="org.apache.ibatis.parsing.PropertyParser.default-value-separator" value="?:"/> <!-- Change default value of separator -->
</properties>]]></source>
        <source><![CDATA[
<dataSource type="POOLED">
  <!-- ... -->
  <property name="username" value="${db:username?:ut_user}"/>
</dataSource>]]></source>

      </subsection>
      <subsection name="settings">
        <p>
          These are extremely important tweaks that modify the way that
          MyBatis
          behaves at runtime. The following table describes the
          settings,
          their meanings and their default values.
        </p>

        <table>
          <thead>
            <tr>
              <th>Setting</th>
              <th>Description</th>
              <th>Valid Values</th>
              <th>Default</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>
                cacheEnabled
              </td>
              <td>
                Globally enables or disables any
                caches configured in any
                mapper under this configuration.
              </td>
              <td>
                true | false
              </td>
              <td>
                true
              </td>
            </tr>
            <tr>
              <td>
                lazyLoadingEnabled
              </td>
              <td>
                Globally enables or disables lazy loading. When enabled, all relations will be lazily loaded.
                This value can be superseded for an specific relation by using the <code>fetchType</code> attribute on it.
              </td>
              <td>
                true | false
              </td>
              <td>
                false
              </td>
            </tr>
            <tr>
              <td>
                aggressiveLazyLoading
              </td>
              <td>
                When enabled, any method call will load all the lazy properties of the object. Otherwise, each property is loaded on demand (see also <code>lazyLoadTriggerMethods</code>).
              </td>
              <td>
                true | false
              </td>
              <td>
                false (true in ≤3.4.1)
              </td>
            </tr>
            <tr>
              <td>
                multipleResultSetsEnabled
              </td>
              <td>
                Allows or disallows multiple
                ResultSets to be returned from a
                single statement (compatible
                driver required).
              </td>
              <td>
                true | false
              </td>
              <td>
                true
              </td>
            </tr>
            <tr>
              <td>
                useColumnLabel
              </td>
              <td>
                Uses the column label instead of
                the column name. Different
                drivers behave differently in this
                respect. Refer to the driver
                documentation, or test out both
                modes to determine how your
                driver
                behaves.
              </td>
              <td>
                true | false
              </td>
              <td>
                true
              </td>
            </tr>
            <tr>
              <td>
                useGeneratedKeys
              </td>
              <td>
                Allows JDBC support for generated
                keys. A compatible driver is
                required. This setting forces
                generated keys to be used if set to
                true, as some drivers deny
                compatibility but still work (e.g.
                Derby).
              </td>
              <td>
                true | false
              </td>
              <td>
                False
              </td>
            </tr>
            <tr>
              <td>
                autoMappingBehavior
              </td>
              <td>
                Specifies if and how MyBatis
                should automatically map columns
                to fields/properties.
                NONE disables auto-mapping.
                PARTIAL will only auto-map results
                with no nested result mappings defined inside.
                FULL will auto-map result mappings of any
                complexity (containing nested or otherwise).
              </td>
              <td>
                NONE, PARTIAL, FULL
              </td>
              <td>
                PARTIAL
              </td>
            </tr>
            <tr>
              <td>
                autoMappingUnknownColumnBehavior
              </td>
              <td>
                Specify the behavior when detects an unknown column (or unknown property type) of automatic mapping target.
                <ul>
                  <li><code>NONE</code>: Do nothing</li>
                  <li><code>WARNING</code>: Output warning log (The log level of <code>'org.apache.ibatis.session.AutoMappingUnknownColumnBehavior'</code> must be set to <code>WARN</code>)</li>
                  <li><code>FAILING</code>: Fail mapping (Throw <code>SqlSessionException</code>)</li>
                </ul>
              </td>
              <td>
                NONE, WARNING, FAILING
              </td>
              <td>
                NONE
              </td>
            </tr>
            <tr>
              <td>
                defaultExecutorType
              </td>
              <td>
                Configures the default executor.
                SIMPLE executor does nothing
                special. REUSE executor reuses
                prepared statements. BATCH
                executor
                reuses statements and
                batches updates.
              </td>
              <td>
                SIMPLE
                REUSE
                BATCH
              </td>
              <td>
                SIMPLE
              </td>
            </tr>
            <tr>
              <td>
                defaultStatementTimeout
              </td>
              <td>
                Sets the number of seconds
                the driver will wait
                for a response from the database.
              </td>
              <td>
                Any positive integer
              </td>
              <td>
                Not Set (null)
              </td>
            </tr>
            <tr>
              <td>
                defaultFetchSize
              </td>
              <td>
                Sets the driver a hint as to control fetching size for return results.
                This parameter value can be override by a query setting.
              </td>
              <td>
                Any positive integer
              </td>
              <td>
                Not Set (null)
              </td>
            </tr>
            <tr>
              <td>
                defaultResultSetType
              </td>
              <td>
                Specifies a scroll strategy when omit it per statement settings. (Since: 3.5.2)
              </td>
              <td>
                FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(same behavior with 'Not Set')
              </td>
              <td>
                Not Set (null)
              </td>
            </tr>
            <tr>
              <td>
                safeRowBoundsEnabled
              </td>
              <td>
                Allows using RowBounds on nested
                statements. If allow, set the false.
              </td>
              <td>
                true | false
              </td>
              <td>
                False
              </td>
            </tr>
            <tr>
              <td>
                safeResultHandlerEnabled
              </td>
              <td>
                Allows using ResultHandler on nested statements.
                If allow, set the false.
              </td>
              <td>
                true | false
              </td>
              <td>
                True
              </td>
            </tr>
            <tr>
              <td>
                mapUnderscoreToCamelCase
              </td>
              <td>
                Enables automatic mapping from
                classic database column names
                A_COLUMN to camel case classic Java
                property names aColumn.
              </td>
              <td>
                true | false
              </td>
              <td>
                False
              </td>
            </tr>
            <tr>
              <td>
                localCacheScope
              </td>
              <td>
                MyBatis uses local cache to prevent circular references and speed up repeated nested queries.
                By default (SESSION) all queries executed during a session are cached. If localCacheScope=STATEMENT local session will be used just for
                statement execution, no data will be shared between two different calls to the same SqlSession.
              </td>
              <td>
                SESSION | STATEMENT
              </td>
              <td>
                SESSION
              </td>
            </tr>
            <tr>
              <td>
                jdbcTypeForNull
              </td>
              <td>
                Specifies the JDBC type for null values when no specific JDBC type was provided for the parameter.
                Some drivers require specifying the column JDBC type but others work with generic values like NULL, VARCHAR or OTHER.
              </td>
              <td>
                JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER
              </td>
              <td>
                OTHER
              </td>
            </tr>
            <tr>
              <td>
                lazyLoadTriggerMethods
              </td>
              <td>
                Specifies which Object's methods trigger a lazy load
              </td>
              <td>
                A method name list separated by commas
              </td>
              <td>
                equals,clone,hashCode,toString
              </td>
            </tr>
            <tr>
              <td>
                defaultScriptingLanguage
              </td>
              <td>
                Specifies the language used by default for dynamic SQL generation.
              </td>
              <td>
                A type alias or fully qualified class name.
              </td>
              <td>
                org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
              </td>
            </tr>
            <tr>
              <td>
                defaultEnumTypeHandler
              </td>
              <td>
                Specifies the <code>TypeHandler</code> used by default for Enum. (Since: 3.4.5)
              </td>
              <td>
                A type alias or fully qualified class name.
              </td>
              <td>
                org.apache.ibatis.type.EnumTypeHandler
              </td>
            </tr>
            <tr>
              <td>
                callSettersOnNulls
              </td>
              <td>
                Specifies if setters or map's put method will be called when a retrieved value is null. It is useful when you rely on Map.keySet() or null value initialization. Note primitives such as (int,boolean,etc.) will not be set to null.
              </td>
              <td>
                true | false
              </td>
              <td>
                false
              </td>
            </tr>
            <tr>
              <td>
                returnInstanceForEmptyRow
              </td>
              <td>
                MyBatis, by default, returns <code>null</code> when all the columns of a returned row are NULL.
                When this setting is enabled, MyBatis returns an empty instance instead.
                Note that it is also applied to nested results (i.e. collectioin and association). Since: 3.4.2
              </td>
              <td>
                true | false
              </td>
              <td>
                false
              </td>
            </tr>
            <tr>
              <td>
                logPrefix
              </td>
              <td>
                Specifies the prefix string that MyBatis will add to the logger names.
              </td>
              <td>
                Any String
              </td>
              <td>
                Not set
              </td>
            </tr>
            <tr>
              <td>
                logImpl
              </td>
              <td>
                Specifies which logging implementation MyBatis should use. If this setting is not present logging implementation will be autodiscovered.
              </td>
              <td>
                SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING
              </td>
              <td>
                Not set
              </td>
            </tr>
            <tr>
              <td>
                proxyFactory
              </td>
              <td>
                Specifies the proxy tool that MyBatis will use for creating lazy loading capable objects.
              </td>
              <td>
                CGLIB | JAVASSIST
              </td>
              <td>
                JAVASSIST (MyBatis 3.3 or above)
              </td>
            </tr>
            <tr>
              <td>
                vfsImpl
              </td>
              <td>
                Specifies VFS implementations
              </td>
              <td>
                Fully qualified class names of custom VFS implementation separated by commas.
              </td>
              <td>
                Not set
              </td>
            </tr>
            <tr>
              <td>
                useActualParamName
              </td>
              <td>
                Allow referencing statement parameters by their actual names declared in the method signature.
                To use this feature, your project must be compiled in Java 8 with <code>-parameters</code> option. (Since: 3.4.1)
              </td>
              <td>
                true | false
              </td>
              <td>
                true
              </td>
            </tr>
            <tr>
              <td>
                configurationFactory
              </td>
              <td>
                Specifies the class that provides an instance of <code>Configuration</code>.
                The returned Configuration instance is used to load lazy properties of deserialized objects.
                This class must have a method with a signature <code>static Configuration getConfiguration()</code>. (Since: 3.2.3)
              </td>
              <td>
                A type alias or fully qualified class name.
              </td>
              <td>
                Not set
              </td>
            </tr>
          </tbody>
        </table>
        <p>
          An example of the settings element fully configured is as follows:
        </p>
        <source><![CDATA[<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="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <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"
    value="equals,clone,hashCode,toString"/>
</settings>]]></source>

      </subsection>
      <subsection name="typeAliases">
        <p>
          A type alias is simply a shorter name for a Java type. It's only
          relevant to the XML configuration and simply exists to reduce
          redundant typing of fully qualified classnames. For example:
        </p>
        <source><![CDATA[<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
]]></source>
        <p>
          With this configuration,
          <code>Blog</code>
          can now be used anywhere that
          <code>domain.blog.Blog</code>
          could be.
        </p>
        <p> You can also specify a package where MyBatis will search for
          beans. For example:
        </p>
        <source><![CDATA[<typeAliases>
  <package name="domain.blog"/>
</typeAliases>
]]></source>
        <p>
          Each bean found in
          <code>domain.blog</code>
          , if no annotation is found,
          will be registered as an alias
          using
          uncapitalized non-qualified class name of the bean. That is
          <code>domain.blog.Author</code>
          will be registered as
          <code>author</code>. If the
          <code>@Alias</code>
          annotation is found its value will
          be used as an alias. See the example below:
        </p>
        <source><![CDATA[@Alias("author")
public class Author {
    ...
}
]]></source>
        <p>
          There are many built-in type aliases for common Java types. They
          are all
          case insensitive, note the special handling of primitives
          due
          to the overloaded names.
        </p>
        <table>
          <thead>
            <tr>
              <th>
                Alias
              </th>
              <th>
                Mapped Type
              </th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>
                _byte
              </td>
              <td>
                byte
              </td>
            </tr>
            <tr>
              <td>
                _long
              </td>
              <td>
                long
              </td>
            </tr>
            <tr>
              <td>
                _short
              </td>
              <td>
                short
              </td>
            </tr>
            <tr>
              <td>
                _int
              </td>
              <td>
                int
              </td>
            </tr>
            <tr>
              <td>
                _integer
              </td>
              <td>
                int
              </td>
            </tr>
            <tr>
              <td>
                _double
              </td>
              <td>
                double
              </td>
            </tr>
            <tr>
              <td>
                _float
              </td>
              <td>
                float
              </td>
            </tr>
            <tr>
              <td>
                _boolean
              </td>
              <td>
                boolean
              </td>
            </tr>
            <tr>
              <td>
                string
              </td>
              <td>
                String
              </td>
            </tr>
            <tr>
              <td>
                byte
              </td>
              <td>
                Byte
              </td>
            </tr>
            <tr>
              <td>
                long
              </td>
              <td>
                Long
              </td>
            </tr>
            <tr>
              <td>
                short
              </td>
              <td>
                Short
              </td>
            </tr>
            <tr>
              <td>
                int
              </td>
              <td>
                Integer
              </td>
            </tr>
            <tr>
              <td>
                integer
              </td>
              <td>
                Integer
              </td>
            </tr>
            <tr>
              <td>
                double
              </td>
              <td>
                Double
              </td>
            </tr>
            <tr>
              <td>
                float
              </td>
              <td>
                Float
              </td>
            </tr>
            <tr>
              <td>
                boolean
              </td>
              <td>
                Boolean
              </td>
            </tr>
            <tr>
              <td>
                date
              </td>
              <td>
                Date
              </td>
            </tr>
            <tr>
              <td>
                decimal
              </td>
              <td>
                BigDecimal
              </td>
            </tr>
            <tr>
              <td>
                bigdecimal
              </td>
              <td>
                BigDecimal
              </td>
            </tr>
            <tr>
              <td>
                object
              </td>
              <td>
                Object
              </td>
            </tr>
            <tr>
              <td>
                map
              </td>
              <td>
                Map
              </td>
            </tr>
            <tr>
              <td>
                hashmap
              </td>
              <td>
                HashMap
              </td>
            </tr>
            <tr>
              <td>
                list
              </td>
              <td>
                List
              </td>
            </tr>
            <tr>
              <td>
                arraylist
              </td>
              <td>
                ArrayList
              </td>
            </tr>
            <tr>
              <td>
                collection
              </td>
              <td>
                Collection
              </td>
            </tr>
            <tr>
              <td>
                iterator
              </td>
              <td>
                Iterator
              </td>
            </tr>
          </tbody>
        </table>
      </subsection>
      <subsection name="typeHandlers">
        <p>
          Whenever MyBatis sets a parameter on a PreparedStatement or
          retrieves a
          value from a ResultSet, a TypeHandler is used to retrieve
          the value
          in a means appropriate to the Java type. The following
          table
          describes the default TypeHandlers.
        </p>
        <p>
          <span class="label important">NOTE</span>
          Since version 3.4.5, The MyBatis has been supported JSR-310(Date and Time API) by default.
        </p>
        <table>
          <thead>
            <tr>
              <th>
                Type Handler
              </th>
              <th>
                Java Types
              </th>
              <th>
                JDBC Types
              </th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>
                <code>BooleanTypeHandler</code>
              </td>
              <td>
                <code>java.lang.Boolean</code>, <code>boolean</code>
              </td>
              <td>
                Any compatible <code>BOOLEAN</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>ByteTypeHandler</code>
              </td>
              <td>
                <code>java.lang.Byte</code>, <code>byte</code>
              </td>
              <td>
                Any compatible <code>NUMERIC</code> or <code>BYTE</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>ShortTypeHandler</code>
              </td>
              <td>
                <code>java.lang.Short</code>, <code>short</code>
              </td>
              <td>
                Any compatible <code>NUMERIC</code> or <code>SMALLINT</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>IntegerTypeHandler</code>
              </td>
              <td>
                <code>java.lang.Integer</code>, <code>int</code>
              </td>
              <td>
                Any compatible <code>NUMERIC</code> or <code>INTEGER</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>LongTypeHandler</code>
              </td>
              <td>
                <code>java.lang.Long</code>, <code>long</code>
              </td>
              <td>
                Any compatible <code>NUMERIC</code> or <code>BIGINT</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>FloatTypeHandler</code>
              </td>
              <td>
                <code>java.lang.Float</code>, <code>float</code>
              </td>
              <td>
                Any compatible <code>NUMERIC</code> or <code>FLOAT</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>DoubleTypeHandler</code>
              </td>
              <td>
                <code>java.lang.Double</code>, <code>double</code>
              </td>
              <td>
                Any compatible <code>NUMERIC</code> or <code>DOUBLE</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>BigDecimalTypeHandler</code>
              </td>
              <td>
                <code>java.math.BigDecimal</code>
              </td>
              <td>
                Any compatible <code>NUMERIC</code> or <code>DECIMAL</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>StringTypeHandler</code>
              </td>
              <td>
                <code>java.lang.String</code>
              </td>
              <td>
                <code>CHAR</code>, <code>VARCHAR</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>ClobReaderTypeHandler</code>
              </td>
              <td>
                <code>java.io.Reader</code>
              </td>
              <td>
                -
              </td>
            </tr>
            <tr>
              <td>
                <code>ClobTypeHandler</code>
              </td>
              <td>
                <code>java.lang.String</code>
              </td>
              <td>
                <code>CLOB</code>, <code>LONGVARCHAR</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>NStringTypeHandler</code>
              </td>
              <td>
                <code>java.lang.String</code>
              </td>
              <td>
                <code>NVARCHAR</code>, <code>NCHAR</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>NClobTypeHandler</code>
              </td>
              <td>
                <code>java.lang.String</code>
              </td>
              <td>
                <code>NCLOB</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>BlobInputStreamTypeHandler</code>
              </td>
              <td>
                <code>java.io.InputStream</code>
              </td>
              <td>
                -
              </td>
            </tr>
            <tr>
              <td>
                <code>ByteArrayTypeHandler</code>
              </td>
              <td>
                <code>byte[]</code>
              </td>
              <td>
                Any compatible byte stream type
              </td>
            </tr>
            <tr>
              <td>
                <code>BlobTypeHandler</code>
              </td>
              <td>
                <code>byte[]</code>
              </td>
              <td>
                <code>BLOB</code>, <code>LONGVARBINARY</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>DateTypeHandler</code>
              </td>
              <td>
                <code>java.util.Date</code>
              </td>
              <td>
                <code>TIMESTAMP</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>DateOnlyTypeHandler</code>
              </td>
              <td>
                <code>java.util.Date</code>
              </td>
              <td>
                <code>DATE</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>TimeOnlyTypeHandler</code>
              </td>
              <td>
                <code>java.util.Date</code>
              </td>
              <td>
                <code>TIME</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>SqlTimestampTypeHandler</code>
              </td>
              <td>
                <code>java.sql.Timestamp</code>
              </td>
              <td>
                <code>TIMESTAMP</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>SqlDateTypeHandler</code>
              </td>
              <td>
                <code>java.sql.Date</code>
              </td>
              <td>
                <code>DATE</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>SqlTimeTypeHandler</code>
              </td>
              <td>
                <code>java.sql.Time</code>
              </td>
              <td>
                <code>TIME</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>ObjectTypeHandler</code>
              </td>
              <td>
                Any
              </td>
              <td>
                <code>OTHER</code>, or unspecified
              </td>
            </tr>
            <tr>
              <td>
                <code>EnumTypeHandler</code>
              </td>
              <td>
                Enumeration Type
              </td>
              <td>
                <code>VARCHAR</code> any string compatible type, as the code is stored (not  index).
              </td>
            </tr>
            <tr>
              <td>
                <code>EnumOrdinalTypeHandler</code>
              </td>
              <td>
                Enumeration Type
              </td>
              <td>
                Any compatible <code>NUMERIC</code> or <code>DOUBLE</code>, as the position is stored
                (not the code itself).
              </td>
            </tr>
            <tr>
              <td>
                <code>SqlxmlTypeHandler</code>
              </td>
              <td>
                <code>java.lang.String</code>
              </td>
              <td>
                <code>SQLXML</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>InstantTypeHandler</code>
              </td>
              <td>
                <code>java.time.Instant</code>
              </td>
              <td>
                <code>TIMESTAMP</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>LocalDateTimeTypeHandler</code>
              </td>
              <td>
                <code>java.time.LocalDateTime</code>
              </td>
              <td>
                <code>TIMESTAMP</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>LocalDateTypeHandler</code>
              </td>
              <td>
                <code>java.time.LocalDate</code>
              </td>
              <td>
                <code>DATE</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>LocalTimeTypeHandler</code>
              </td>
              <td>
                <code>java.time.LocalTime</code>
              </td>
              <td>
                <code>TIME</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>OffsetDateTimeTypeHandler</code>
              </td>
              <td>
                <code>java.time.OffsetDateTime</code>
              </td>
              <td>
                <code>TIMESTAMP</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>OffsetTimeTypeHandler</code>
              </td>
              <td>
                <code>java.time.OffsetTime</code>
              </td>
              <td>
                <code>TIME</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>ZonedDateTimeTypeHandler</code>
              </td>
              <td>
                <code>java.time.ZonedDateTime</code>
              </td>
              <td>
                <code>TIMESTAMP</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>YearTypeHandler</code>
              </td>
              <td>
                <code>java.time.Year</code>
              </td>
              <td>
                <code>INTEGER</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>MonthTypeHandler</code>
              </td>
              <td>
                <code>java.time.Month</code>
              </td>
              <td>
                <code>INTEGER</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>YearMonthTypeHandler</code>
              </td>
              <td>
                <code>java.time.YearMonth</code>
              </td>
              <td>
                <code>VARCHAR</code> or <code>LONGVARCHAR</code>
              </td>
            </tr>
            <tr>
              <td>
                <code>JapaneseDateTypeHandler</code>
              </td>
              <td>
                <code>java.time.chrono.JapaneseDate</code>
              </td>
              <td>
                <code>DATE</code>
              </td>
            </tr>
          </tbody>
        </table>
        <p>
          You can override the type handlers or create your own to deal with
          unsupported or non-standard types. To do so, implement the interface <code>org.apache.ibatis.type.TypeHandler</code>
          or extend the convenience class <code>org.apache.ibatis.type.BaseTypeHandler</code>
          and optionally map it to a JDBC type. For example:
        </p>

        <source><![CDATA[// ExampleTypeHandler.java
@MappedJdbcTypes(JdbcType.VARCHAR)
public class ExampleTypeHandler extends BaseTypeHandler<String> {

  @Override
  public void setNonNullParameter(PreparedStatement ps, int i,
    String parameter, JdbcType jdbcType) throws SQLException {
    ps.setString(i, parameter);
  }

  @Override
  public String getNullableResult(ResultSet rs, String columnName)
    throws SQLException {
    return rs.getString(columnName);
  }

  @Override
  public String getNullableResult(ResultSet rs, int columnIndex)
    throws SQLException {
    return rs.getString(columnIndex);
  }

  @Override
  public String getNullableResult(CallableStatement cs, int columnIndex)
    throws SQLException {
    return cs.getString(columnIndex);
  }
}
]]></source>

        <source><![CDATA[<!-- mybatis-config.xml -->
<typeHandlers>
  <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/>
</typeHandlers>
]]></source>

        <p>
          Using such a TypeHandler would override the existing type handler
          for Java String properties and VARCHAR parameters and results. Note
          that MyBatis does not introspect upon the database metadata to
          determine the type, so you must specify that it’s a VARCHAR field
          in the parameter and result mappings to hook in the correct type
          handler. This is due to the fact that MyBatis is unaware of the
          data type until the statement is executed.
        </p>
        <p>
          MyBatis will know the the Java type that you want to handle with
          this TypeHandler by introspecting its generic type, but
          you can override this behavior by two means:
        </p>
        <ul>
          <li>Adding a <code>javaType</code> attribute to the typeHandler element (for example: <code>javaType="String"</code>)
          </li>
          <li>Adding a <code>@MappedTypes</code> annotation to your TypeHandler class specifying
          the list of java types to associate it with. This annotation will be ignored if
          the <code>javaType</code> attribute as also been specified.
          </li>
        </ul>

        <p>Associated JDBC type can be specified by two means:</p>
        <ul>
          <li>
           Adding a <code>jdbcType</code> attribute to the typeHandler element (for example: <code>jdbcType="VARCHAR"</code>).
          </li>
          <li>Adding a <code>@MappedJdbcTypes</code> annotation to your TypeHandler class specifying
          the list of JDBC types to associate it with. This annotation will be ignored if
          the <code>jdbcType</code> attribute as also been specified.
          </li>
        </ul>

        <p>
          When deciding which TypeHandler to use in a <code>ResultMap</code>, the Java type is known
          (from the result type), but the JDBC type is unknown. MyBatis therefore uses the combination
          <code>javaType=[TheJavaType], jdbcType=null</code> to choose a TypeHandler. This means that
          using a <code>@MappedJdbcTypes</code> annotation <i>restricts</i> the scope of a TypeHandler
          and makes it unavailable for use in <code>ResultMap</code>s unless explicity set. To make a
          TypeHandler available for use in a <code>ResultMap</code>, set <code>includeNullJdbcType=true</code>
          on the <code>@MappedJdbcTypes</code> annotation. Since Mybatis 3.4.0 however, if a <b>single</b>
          TypeHandler is registered to handle a Java type, it will be used by default in <code>ResultMap</code>s
          using this Java type (i.e. even without <code>includeNullJdbcType=true</code>).
        </p>

        <p>And finally you can let MyBatis search for your TypeHandlers:</p>
        <source><![CDATA[<!-- mybatis-config.xml -->
<typeHandlers>
  <package name="org.mybatis.example"/>
</typeHandlers>
]]></source>

        <p>
          Note that when using the autodiscovery feature JDBC types can only be
          specified with annotations.
        </p>

        <p>
          You can create a generic TypeHandler that is able to handle more than one class. For that purpose
          add a constructor that receives the class as a parameter and MyBatis will pass the actual class when
          constructing the TypeHandler.
        </p>

        <source><![CDATA[//GenericTypeHandler.java
public class GenericTypeHandler<E extends MyObject> extends BaseTypeHandler<E> {

  private Class<E> type;

  public GenericTypeHandler(Class<E> type) {
    if (type == null) throw new IllegalArgumentException("Type argument cannot be null");
    this.type = type;
  }
  ...
]]></source>

        <p><code>EnumTypeHandler</code> and <code>EnumOrdinalTypeHandler</code> are generic TypeHandlers. We will learn
        about them in the following section.
        </p>

      </subsection>

      <subsection name="Handling Enums">
          <p>
            If you want to map an <code>Enum</code>, you'll need to use either
            <code>EnumTypeHandler</code> or <code>EnumOrdinalTypeHandler</code>.
          </p>

          <p>For example, let's say that we need to store the rounding mode that
          should be used with some number if it needs to be rounded. By default, MyBatis
          uses <code>EnumTypeHandler</code> to convert the <code>Enum</code>
          values to their names.
          </p>

          <b>Note <code>EnumTypeHandler</code> is special in the sense that unlike other handlers,
          it does not handle just one specific class, but any class that extends <code>Enum</code></b>

          <p>However, we may not want to store names. Our DBA may insist on an
          integer code instead. That's just as easy: add <code>EnumOrdinalTypeHandler</code>
          to the <code>typeHandlers</code> in your config file, and now each
          <code>RoundingMode</code> will be mapped to an integer using its ordinal value.
          </p>
       <source><![CDATA[<!-- mybatis-config.xml -->
<typeHandlers>
  <typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
    javaType="java.math.RoundingMode"/>
</typeHandlers>
]]></source>
        <p>
          But what if you want to map the same <code>Enum</code> to a
          string in one place and to integer in another?
        </p>
          <p>
            The auto-mapper will automatically use <code>EnumOrdinalTypeHandler</code>,
            so if we want to go back to using plain old ordinary
            <code>EnumTypeHandler</code>, we have to tell it, by explicitly setting
            the type handler to use for those SQL statements.
          </p>
          <p>
            (Mapper files aren't covered until the next section, so if this is your first
            time reading through the documentation, you may want to skip this for now
            and come back to it later.)
          </p>
          <source><![CDATA[<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.apache.ibatis.submitted.rounding.Mapper">
    <resultMap type="org.apache.ibatis.submitted.rounding.User" id="usermap">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="funkyNumber" property="funkyNumber"/>
        <result column="roundingMode" property="roundingMode"/>
    </resultMap>

    <select id="getUser" resultMap="usermap">
        select * from users
    </select>
    <insert id="insert">
        insert into users (id, name, funkyNumber, roundingMode) values (
            #{id}, #{name}, #{funkyNumber}, #{roundingMode}
        )
    </insert>

    <resultMap type="org.apache.ibatis.submitted.rounding.User" id="usermap2">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="funkyNumber" property="funkyNumber"/>
        <result column="roundingMode" property="roundingMode"
         typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
    </resultMap>
    <select id="getUser2" resultMap="usermap2">
        select * from users2
    </select>
    <insert id="insert2">
        insert into users2 (id, name, funkyNumber, roundingMode) values (
            #{id}, #{name}, #{funkyNumber}, #{roundingMode, typeHandler=org.apache.ibatis.type.EnumTypeHandler}
        )
    </insert>

</mapper>
]]></source>
        <p>
          Note that this forces us to use a <code>resultMap</code>
          instead of a <code>resultType</code> in our select statements.
        </p>
      </subsection>

      <subsection name="objectFactory">
        <p>
          Each time MyBatis creates a new instance of a result object, it
          uses an
          ObjectFactory instance to do so. The default ObjectFactory
          does
          little more than instantiate the target class with a default
          constructor, or a parameterized constructor if parameter mappings
          exist. If you want to override the default behaviour of the
          ObjectFactory, you can create your own. For example:
        </p>
        <source><![CDATA[// ExampleObjectFactory.java
public class ExampleObjectFactory extends DefaultObjectFactory {
  public Object create(Class type) {
    return super.create(type);
  }
  public Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs) {
    return super.create(type, constructorArgTypes, constructorArgs);
  }
  public void setProperties(Properties properties) {
    super.setProperties(properties);
  }
  public <T> boolean isCollection(Class<T> type) {
    return Collection.class.isAssignableFrom(type);
  }}
]]></source>

        <source><![CDATA[<!-- mybatis-config.xml -->
<objectFactory type="org.mybatis.example.ExampleObjectFactory">
  <property name="someProperty" value="100"/>
</objectFactory>]]></source>
        <p>
          The ObjectFactory interface is very simple. It contains two create
          methods, one to deal with the default constructor, and the other to
          deal with parameterized constructors. Finally, the setProperties
          method can be used to configure the ObjectFactory. Properties
          defined within the body of the objectFactory element will be passed
          to the setProperties method after initialization of your
          ObjectFactory instance.
        </p>

      </subsection>
      <subsection name="plugins">
        <p>
          MyBatis allows you to intercept calls to at certain points within
          the
          execution of a mapped statement. By default, MyBatis allows
          plug-ins to intercept method calls of:
        </p>
        <ul>
          <li>
            Executor
            (update, query, flushStatements, commit, rollback,
            getTransaction, close,
            isClosed)
          </li>
          <li>
            ParameterHandler
            (getParameterObject, setParameters)
          </li>
          <li>
            ResultSetHandler
            (handleResultSets, handleOutputParameters)
          </li>
          <li>
            StatementHandler
            (prepare, parameterize, batch, update, query)
          </li>
        </ul>
        <p>
          The details of these classes methods can be discovered by looking
          at
          the full method signature of each, and the source code which is
          available with each MyBatis release. You should understand the
          behaviour of the method you’re overriding, assuming you’re doing
          something more than just monitoring calls. If you attempt to modify
          or override the behaviour of a given method, you’re likely to break
          the core of MyBatis. These are low level classes and methods, so
          use
          plug-ins with caution.
        </p>
        <p>
          Using plug-ins is pretty simple given the power they provide.
          Simply
          implement the Interceptor interface, being sure to specify the
          signatures you want to intercept.
        </p>

        <source><![CDATA[// ExamplePlugin.java
@Intercepts({@Signature(
  type= Executor.class,
  method = "update",
  args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
  private Properties properties = new Properties();
  public Object intercept(Invocation invocation) throws Throwable {
    // implement pre processing if need
    Object returnObject = invocation.proceed();
    // implement post processing if need
    return returnObject;
  }
  public void setProperties(Properties properties) {
    this.properties = properties;
  }
}]]></source>

        <source><![CDATA[<!-- mybatis-config.xml -->
<plugins>
  <plugin interceptor="org.mybatis.example.ExamplePlugin">
    <property name="someProperty" value="100"/>
  </plugin>
</plugins>]]></source>
        <p>
          The plug-in above will intercept all calls to the "update" method
          on
          the Executor instance, which is an internal object responsible for
          the low level execution of mapped statements.
        </p>
        <p><span class="label important">NOTE</span>
          <strong>Overriding the Configuration Class
          </strong>
        </p>
        <p>
          In addition to modifying core MyBatis behaviour with plugins, you
          can
          also override the Configuration class entirely. Simply extend it
          and override any methods inside, and pass it into the call to the
          SqlSessionFactoryBuilder.build(myConfig) method. Again though, this
          could have a severe impact on the behaviour of MyBatis, so use
          caution.
        </p>
      </subsection>
      <subsection name="environments">
        <p>
          MyBatis can be configured with multiple environments. This helps
          you to
          apply your SQL Maps to multiple databases for any number of
          reasons. For example, you might have a different configuration for
          your Development, Test and Production environments. Or, you may
          have
          multiple production databases that share the same schema, and
          you’d
          like to use the same SQL maps for both. There are many use
          cases.
        </p>
        <p>
          <strong>One important thing to remember though: While you can
            configure multiple environments, you can only choose ONE per
            SqlSessionFactory instance.
          </strong>
        </p>
        <p>
          So if you want to connect to two databases, you need to create two
          instances of SqlSessionFactory, one for each. For three databases,
          you’d need three instances, and so on. It’s really easy to
          remember:
        </p>
        <ul>
          <li>
            <strong>One SqlSessionFactory instance per database
            </strong>
          </li>
        </ul>
        <p>
          To specify which environment to build, you simply pass it to the
          SqlSessionFactoryBuilder as an optional parameter. The two
          signatures that accept the environment are:
        </p>

        <source><![CDATA[SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);]]></source>

        <p>If the environment is omitted, then the default environment is
          loaded, as follows:
        </p>

        <source><![CDATA[SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);]]></source>

        <p>The environments element defines how the environment is
          configured.
        </p>

        <source><![CDATA[<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED">
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>]]></source>
        <p>
          Notice the key sections here:
        </p>
        <ul>
          <li>
            The default Environment ID (e.g. default="development").
          </li>
          <li>
            The Environment ID for each environment defined (e.g.
            id="development").
          </li>
          <li>
            The TransactionManager configuration (e.g. type="JDBC")
          </li>
          <li>
            The DataSource configuration (e.g. type="POOLED")
          </li>
        </ul>
        <p>
          The default environment and the environment IDs are self
          explanatory.
          Name them whatever you like, just make sure the default
          matches one
          of them.
        </p>
        <p>
          <strong>transactionManager</strong>
        </p>
        <p>
          There are two TransactionManager types (i.e.
          type="[JDBC|MANAGED]") that
          are included with MyBatis:
        </p>
        <ul>
          <li>
            JDBC – This configuration simply makes use of the JDBC commit
            and
            rollback facilities directly. It relies on the connection
            retrieved from the dataSource to manage the scope of the
            transaction.
          </li>
          <li>
            MANAGED – This configuration simply does almost nothing. It
            never
            commits, or rolls back a connection. Instead, it lets the
            container manage the full lifecycle of the transaction (e.g.
            a JEE Application Server context). By default it does
            close the connection. However, some containers don’t expect this,
            and thus if you need to stop it from closing the connection, set
            the "closeConnection" property to false. For example:
            <source><![CDATA[<transactionManager type="MANAGED">
  <property name="closeConnection" value="false"/>
</transactionManager>]]></source>
          </li>
        </ul>
        <p>
          <span class="label important">NOTE</span>
          If you are planning to use MyBatis with Spring there is no need to configure
          any TransactionManager because the Spring module will set its own one
          overriding any previously set configuration.
        </p>
        <p>
          Neither of these TransactionManager types require any properties.
          However,
          they are both Type Aliases, so in other words, instead of
          using
          them, you could put your own fully qualified class name or Type
          Alias that refers to your own implementation of the
          TransactionFactory interface.
        </p>
        <source><![CDATA[public interface TransactionFactory {
  default void setProperties(Properties props) { // Since 3.5.2, change to default method
    // NOP
  }
  Transaction newTransaction(Connection conn);
  Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
}]]></source>
        <p>
          Any properties configured in the XML will be passed to the
          setProperties() method after instantiation. Your implementation
          would also need to create a Transaction implementation, which is
          also a very simple interface:
        </p>
        <source><![CDATA[public interface Transaction {
  Connection getConnection() throws SQLException;
  void commit() throws SQLException;
  void rollback() throws SQLException;
  void close() throws SQLException;
  Integer getTimeout() throws SQLException;
}]]></source>
        <p>
          Using these two interfaces, you can completely customize how
          MyBatis
          deals with Transactions.
        </p>
        <p>
          <strong>dataSource</strong>
        </p>
        <p>
          The dataSource element configures the source of JDBC Connection
          objects using the standard JDBC DataSource interface.
        </p>
        <ul>
          <li>Most MyBatis applications will configure a dataSource as in the
            example. However, it’s not required. Realize though, that to
            facilitate Lazy Loading, this dataSource is required.
          </li>
        </ul>
        <p>There are three build-in dataSource types (i.e. type="[UNPOOLED|POOLED|JNDI]"):
        </p>
        <p>
          <strong>UNPOOLED</strong>
          – This implementation of DataSource simply opens and closes a
          connection each time it is requested. While it’s a bit slower, this
          is a good choice for simple applications that do not require the
          performance of immediately available connections. Different
          databases are also different in this performance area, so for some
          it may be less important to pool and this configuration will be
          ideal. The UNPOOLED DataSource has the following properties to configure:
        </p>
        <ul>
          <li><code>driver</code> – This is the fully qualified Java class of the JDBC
            driver (NOT of the DataSource class if your driver includes one).
          </li>
          <li><code>url</code> – This is the JDBC URL for your database instance.
          </li>
          <li><code>username</code> – The database username to log in with.
          </li>
          <li><code>password</code> - The database password to log in with.
          </li>
          <li><code>defaultTransactionIsolationLevel</code> – The default transaction
            isolation level for connections.
          </li>
          <li><code>defaultNetworkTimeout</code> – The default network timeout value in milliseconds to wait for the database operation to complete. See the API documentation of <code>java.sql.Connection#setNetworkTimeout()</code> for details.
          </li>
        </ul>
        <p>
          Optionally, you can pass properties to the database driver as
          well. To do
          this, prefix the properties with <code>driver.</code>, for example:
        </p>
        <ul>
          <li><code>driver.encoding=UTF8</code></li>
        </ul>
        <p>
          This will pass the property <code>encoding</code>, with the value <code>UTF8</code>, to
          your
          database driver via the <code>DriverManager.getConnection(url,
          driverProperties)</code> method.
        </p>
        <p>
          <strong>POOLED</strong>
          – This implementation of DataSource pools JDBC Connection objects
          to
          avoid the initial connection and authentication time required to
          create a new Connection instance. This is a popular approach for
          concurrent web applications to achieve the fastest response.
        </p>
        <p>
          In addition to the (UNPOOLED) properties above, there are many
          more
          properties that can be used to configure the POOLED datasource:
        </p>
        <ul>
          <li><code>poolMaximumActiveConnections</code> – This is the number of active
            (i.e. in use) connections that can exist at any given time.
            Default: 10
          </li>
          <li><code>poolMaximumIdleConnections</code> – The number of idle connections
            that
            can exist at any given time.
          </li>
          <li><code>poolMaximumCheckoutTime</code> – This is the amount of time that a
            Connection can be "checked out" of the pool before it will be
            forcefully returned. Default: 20000ms (i.e. 20 seconds)
          </li>
          <li><code>poolTimeToWait</code> – This is a low level setting that gives the
            pool
            a chance to print a log status and re-attempt the acquisition
            of a
            connection in the case that it’s taking unusually long (to
            avoid
            failing silently forever if the pool is misconfigured).
            Default:
            20000ms (i.e. 20 seconds)
          </li>
          <li><code>poolMaximumLocalBadConnectionTolerance</code> – This is a low level setting about
            tolerance of bad connections got for any thread. If a thread got a bad connection, it may
            still have another chance to re-attempt to get another connection which is valid. But the
            retrying times should not more than the sum of <code>poolMaximumIdleConnections</code>
            and <code>poolMaximumLocalBadConnectionTolerance</code>.
            Default:
            3 (Since: 3.4.5)
          </li>
          <li><code>poolPingQuery</code> – The Ping Query is sent to the database to
            validate that a connection is in good working order and is ready
            to
            accept requests. The default is "NO PING QUERY SET", which will
            cause most database drivers to fail with a decent error message.
          </li>
          <li><code>poolPingEnabled</code> – This enables or disables the ping query. If
            enabled, you must also set the poolPingQuery property with a valid
            SQL statement (preferably a very fast one). Default: false.
          </li>
          <li><code>poolPingConnectionsNotUsedFor</code> – This configures how often the
            poolPingQuery will be used. This can be set to match the typical
            timeout for a database connection, to avoid unnecessary pings.
            Default: 0 (i.e. all connections are pinged every time – but only
            if poolPingEnabled is true of course).
          </li>
        </ul>
        <p>
          <strong>JNDI</strong>
          – This implementation of DataSource is intended for use with
          containers such as EJB or Application Servers that may configure
          the
          DataSource centrally or externally and place a reference to it
          in a
          JNDI context. This DataSource configuration only requires two
          properties:
        </p>
        <ul>
          <li><code>initial_context</code> – This property is used for the Context lookup
            from the InitialContext (i.e.
            initialContext.lookup(initial_context)). This property is
            optional,
            and if omitted, then the data_source property will be
            looked up
            against the InitialContext directly.
          </li>
          <li><code>data_source</code> – This is the context path where the reference to
            the instance of the DataSource can be found. It will be looked up
            against the context returned by the initial_context lookup, or
            against the InitialContext directly if no initial_context is
            supplied.
          </li>
        </ul>
        <p>Similar to the other DataSource configurations, it’s possible to
          send properties directly to the InitialContext by prefixing those
          properties with <code>env.</code>, for example:
        </p>
        <ul>
          <li><code>env.encoding=UTF8</code></li>
        </ul>
        <p>
          This would send the property <code>encoding</code> with the value of <code>UTF8</code>
          to the
          constructor of the InitialContext upon instantiation.
        </p>

        <p>
          You can plug any 3rd party DataSource by implementing the interface <code>org.apache.ibatis.datasource.DataSourceFactory</code>:
        </p>

        <source><![CDATA[public interface DataSourceFactory {
  void setProperties(Properties props);
  DataSource getDataSource();
}]]></source>

        <p>
          <code>org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory</code> can be used as super class
          to build new datasource adapters. For example this is the code needed to plug C3P0:
        </p>

        <source><![CDATA[import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0DataSourceFactory extends UnpooledDataSourceFactory {

  public C3P0DataSourceFactory() {
    this.dataSource = new ComboPooledDataSource();
  }
}]]></source>

        <p>To set it up, add a property for each setter method you want MyBatis to call.
        Follows below a sample configuration which connects to a PostgreSQL database:</p>

        <source><![CDATA[<dataSource type="org.myproject.C3P0DataSourceFactory">
  <property name="driver" value="org.postgresql.Driver"/>
  <property name="url" value="jdbc:postgresql:mydb"/>
  <property name="username" value="postgres"/>
  <property name="password" value="root"/>
</dataSource>
]]></source>

      </subsection>

      <subsection name="databaseIdProvider">
        <p>
          MyBatis is able to execute different statements depending on your database vendor.
          The multi-db vendor support is based on the mapped statements <code>databaseId</code> attribute.
          MyBatis will load all statements with no <code>databaseId</code> attribute
          or with a <code>databaseId</code> that matches the current one. In case the same statement
          is found with and without the <code>databaseId</code> the latter will be discarded.
          To enable the multi vendor support add a <code>databaseIdProvider</code>
          to mybatis-config.xml file as follows:
        </p>

        <source><![CDATA[<databaseIdProvider type="DB_VENDOR" />
]]></source>

        <p>
          The DB_VENDOR implementation databaseIdProvider sets as databaseId the String returned by
          <code>DatabaseMetaData#getDatabaseProductName()</code>.
          Given that usually that string is too long and that different versions of the same product may return different values,
          you may want to convert it to a shorter one by adding properties like follows:
        </p>

        <source><![CDATA[<databaseIdProvider type="DB_VENDOR">
  <property name="SQL Server" value="sqlserver"/>
  <property name="DB2" value="db2"/>
  <property name="Oracle" value="oracle" />
</databaseIdProvider>]]></source>

        <p>
          When properties are provided, the DB_VENDOR databaseIdProvider will search the property value corresponding to the
          first key found in the returned database product name or "null" if there is not a matching property.
          In this case, if <code>getDatabaseProductName()</code> returns "Oracle (DataDirect)" the databaseId will be set to "oracle".
        </p>

        <p>
          You can build your own DatabaseIdProvider by implementing the interface <code>org.apache.ibatis.mapping.DatabaseIdProvider</code>
          and registering it in mybatis-config.xml:
        </p>

        <source><![CDATA[public interface DatabaseIdProvider {
  default void setProperties(Properties p) { // Since 3.5.2, change to default method
    // NOP
  }
  String getDatabaseId(DataSource dataSource) throws SQLException;
}]]></source>

      </subsection>

      <subsection name="mappers">
        <p>
          Now that the behavior of MyBatis is configured with the above
          configuration elements, we’re ready to define our mapped SQL
          statements. But first, we need to tell MyBatis where to find them.
          Java doesn’t really provide any good means of auto-discovery in
          this regard, so the best way to do it is to simply tell MyBatis
          where to find the mapping files. You can use classpath relative
          resource references, fully qualified url references
          (including <code>file:///</code> URLs), class names or package names.
          For example:
        </p>
        <source><![CDATA[<!-- Using classpath relative resources -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>]]></source>

        <source><![CDATA[<!-- Using url fully qualified paths -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>]]></source>

        <source><![CDATA[<!-- Using mapper interface classes -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>]]></source>

        <source><![CDATA[<!-- Register all interfaces in a package as mappers -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>]]></source>

        <p>
          These statement simply tell MyBatis where to go from here. The
          rest of the details are in each of the SQL Mapping files, and that’s
          exactly what the next section will discuss.
        </p>
      </subsection>
    </section>
  </body>
</document>
