Mybatis learning record 02 - mybatis configuration


mybatis-config.xml system core configuration file
The MyBatis configuration file contains settings and attribute information that deeply affect MyBatis behavior. The top-level structure of the configuration document is as follows:

  • configuration
  • properties
  • settings
  • typeAliases
  • typeHandlers
  • objectFactory (object factory)
  • plugins
  • environments
    • Environment (environment variable)
    • Transaction manager
    • dataSource
  • databaseIdProvider (database vendor ID)
  • mappers

You need to configure according to the order structure during configuration, otherwise an error will be reported

Environment configurations

MyBatis can be configured to adapt to a variety of environments. This mechanism helps to apply SQL mapping to a variety of databases. In reality, there are many reasons to do so. For example, development, test and production environments need different configurations; Or you want to use the same SQL mapping in multiple production databases with the same Schema. There are many similar usage scenarios.

However, remember that although multiple environments can be configured, only one environment can be selected for each SqlSessionFactory instance.

Therefore, if you want to connect two databases, you need to create two SqlSessionFactory instances, one for each database. If there are three databases, three instances are required, and so on

The environments element defines how to configure the environment:

<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>

be careful:

  • The default environment ID (for example, default = "development").
  • The environment ID defined by each environment element (for example: id = "development").
  • Configuration of the transaction manager (for example: type = "JDBC").
  • Configuration of data source (for example, type = "POOLED").
  • The default environment and environment ID are as the name suggests. The environment can be named at will, but it must be ensured that the default environment ID matches one of the environment IDS, for example:
<!--  default="development" Default use id by development Environment -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!--      &Need escape -> &amp;         -->
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!--      &Need escape -> &amp;         -->
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

Transaction manager

There are two types of transaction managers in MyBatis (that is, type="[JDBC|MANAGED]):

  • JDBC – this configuration directly uses JDBC's commit and rollback facilities, which rely on connections obtained from data sources to manage transaction scopes.
  • MANAGED – this configuration does little. It never commits or rolls back a connection, but lets the container manage the entire life cycle of the transaction (such as the context of the JEE application server). By default, it closes the connection. However, some containers do not want the connection to be closed, so you need to set the closeConnection property to false to prevent the default closing behavior. For example:
<transactionManager type="MANAGED">
  <property name="closeConnection" value="false"/>
</transactionManager>
  • We usually use JDBC transaction manager

Data source

The dataSource element uses the standard JDBC data source interface to configure the resources of the JDBC connection object.

  • The data source must be configured.

  • There are three built-in data source types

type="[UNPOOLED|POOLED|JNDI]")
  • unpooled: the implementation of this data source only opens and closes the connection every time it is requested.

  • pooled: the implementation of this data source uses the concept of "pool" to organize JDBC connection objects, which is a popular way to make concurrent Web applications respond to requests quickly.

  • JNDI: this data source is implemented to be used in containers such as Spring or application server. The container can configure the data source centrally or externally, and then place a reference to the JNDI context.

  • Data sources also have many third-party implementations, such as dbcp, c3p0, druid and so on
    See details Official documents

properties

Properties can be configured externally and can be replaced dynamically. These properties can be configured either in a typical Java properties file or in a child element of the properties element. For example:

<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="dev_user"/>
  <property name="password" value="F2Fa3!33TYyg"/>
</properties>

The set attributes can be used in the whole configuration file to replace the attribute values that need to be dynamically configured. For example:
configuration file

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8
username=root
password=root
	<!--  External profile  -->
    <properties resource="db.properties"/>

    <!--  default="development" Default use id by development Environment -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
            	<!-- adopt ${}Value-->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

Type aliases

Type alias sets an abbreviated name for a Java type. It is only used for XML configuration and is intended to reduce redundant fully qualified class name writing. For example:

<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>

When configured in this way, blog can be used in any domain blog. Blog place.

<!--  alias  -->
    <typeAliases>
        <typeAlias type="com.wcy.pojo.User" alias="User"/>
    </typeAliases>
<!--parameterType Can write directly User-->
    <insert id="addUser" parameterType="User">
        insert into user (`id`, `name`, `pwd`)
        values (#{id}, #{name}, #{pwd});
    </insert>

You can also specify a package name. MyBatis will search for the required Java beans under the package name, such as:

<typeAliases>
  <package name="com.wcy.pojo"/>
</typeAliases>

Every one in the package com wcy. Java beans in POJO, without annotations, will use the initial lowercase unqualified class name of the Bean as its alias. Like com wcy. pojo. The alias of user is user; If there is an annotation, the alias is its annotation value. See the following example:

@Alias("user")
public class User{
    ...
}

Here are some built-in type aliases for common Java types. They are case insensitive. Note that in order to deal with the naming repetition of the original type, a special naming style is adopted.

aliasType of mapping
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator

settings

An example of a fully configured settings element is as follows:
See the following for functions: Official documents

<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>

Mappers

Mapper: define mapping SQL statement files

Now that the behavior of MyBatis and other elements have been configured, we are going to define the SQL mapping statement. But first we need to tell MyBatis where to find these statements. Java does not provide a good way to automatically find this, so the best way is to tell MyBatis where to find the mapping file. You can use resource references relative to the classpath, or fully qualified resource locators (including the URL of file: / /), or class and package names. Mapper is one of the core components in MyBatis. Before MyBatis 3, only xml mapper was supported, that is, all SQL statements must be configured in xml files. Starting from MyBatis 3, it also supports interface mapper, which allows the annotation and definition of SQL statements in the form of Java code, which is very concise.

Resource introduction method

<!-- Use resource references relative to Classpaths -->
<mappers>
 <mapper resource="com/wcy/dao/UserMapper.xml"/>
</mappers>
<!-- Use fully qualified resource locators( URL) -->
<mappers>
 <mapper url="file:///var/mappers/AuthorMapper.xml"/>
</mappers>
<!--
Use the mapper interface to implement the fully qualified class name of the class
 The configuration file name and interface name should be consistent and located in the same directory
-->
<mappers>
 <mapper class="com.wcy.dao.UserDao"/>
</mappers>
<!--
Register all the mapper interface implementations in the package as mappers
 However, the configuration file name and interface name should be consistent and located in the same directory
-->
<mappers>
 <package name="com.wcy.dao"/>
</mappers>

Mapper file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wcy.dao.UserMapper">
   
</mapper>

Namespace means namespace in Chinese. Its functions are as follows:

  • The name of a namespace must have the same name as an interface

  • The method in the interface should correspond to the sql statement id in the mapping file one by one

  • The combination of namespace and child element id ensures uniqueness and distinguishes different mapper s

  • Bind DAO interface

  • namespace naming rules: package name + class name

The real power of MyBatis lies in its mapping statements, which is its magic. Because of its extraordinary power, the XML file of the mapper is relatively simple. If you compare it with JDBC code with the same function, you will immediately find that nearly 95% of the code is saved. MyBatis is built to focus on SQL to minimize your trouble.

Scope and lifecycle

It is important to understand the different scopes and lifecycle classes we have discussed so far, because incorrect use can lead to very serious concurrency problems.

We can draw a flow chart to analyze the execution process of Mybatis!

Scope understanding

The function of SqlSessionFactoryBuilder is to create SqlSessionFactory. After the creation is successful, SqlSessionFactoryBuilder will lose its function, so it can only exist in the method of creating SqlSessionFactory, not for a long time. Therefore, the best scope of the SqlSessionFactoryBuilder instance is the method scope (that is, local method variables).

SqlSessionFactory can be considered as a database connection pool. Its function is to create SqlSession interface objects. Because the essence of MyBatis is Java's operation on the database, the life cycle of SqlSessionFactory exists in the whole MyBatis application. Therefore, once SqlSessionFactory is created, it must be saved for a long time until MyBatis application is no longer used. Therefore, it can be considered that the life cycle of SqlSessionFactory is equivalent to the application cycle of MyBatis.

Since SqlSessionFactory is a connection pool to the database, it occupies the connection resources of the database. If multiple sqlsessionfactories are created, there will be multiple database connection pools, which is not conducive to the control of database resources. It will also lead to the depletion of database connection resources and system downtime. Therefore, try to avoid such a situation.

Therefore, in general applications, we often want SqlSessionFactory as a singleton to be shared in the application. Therefore, the best scope of SqlSessionFactory is the application scope.

If SqlSessionFactory is equivalent to a database Connection pool, SqlSession is equivalent to a database Connection (Connection object). You can execute multiple SQL in a transaction, and then commit or roll back the transaction through its commit, rollback and other methods. Therefore, it should survive in a business request. After processing a complete request, close the Connection and return it to SqlSessionFactory. Otherwise, the database resources will be consumed quickly and the system will be paralyzed. Therefore, use the try... catch... finally... Statement to ensure that it is closed correctly.

Therefore, the best scope of SqlSession is the request or method scope. Close it immediately after use.

Keywords: Java Database Mybatis

Added by Imperialdata on Wed, 05 Jan 2022 21:02:30 +0200