MyBatis

preface

1. The required environment

  • JDK 1.8
  • Mysql 8.0
  • Maven 3.8.1
  • IDEA

2. Review relevant technologies

  • JDBC
  • Mysql
  • Java based
  • Maven
  • Junit

1, the introduction of

1.1. What is MyBatis?

  • MyBatis is an excellent persistence layer framework.
  • It supports custom SQL, stored procedures, and advanced mapping.
  • MyBatis eliminates almost all of the JDBC code and the work of setting parameters and fetching result sets.
  • MyBatis can configure and map primitive types, interfaces, and Java POJOs (Plain Old Java Objects) to records in the database via simple XML or annotations.
  • MyBatis is an open source project of Apache called iBatis. In 2010, this project was migrated to Google Code by Apache Software Foundation and renamed as MyBatis.
  • Migrated to Github in November 2013

1.2. How to obtain MyBatis?

  • Obtained from maven repository

    <! -- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    Copy the code
  • Go to GitHub and search: github.com/search?q=My…

  • English: mybatis.org/mybatis-3/z…

1.3. Persistence

1.3.1. Data Persistence

  • Definition: Persistence is the process of converting program data into transient and persistent states
  • Memory features: The memory is lost upon a power failure
  • Persistence means: database, IO file persistence……
  • Examples of life: refrigeration, canning

1.3.2. Why Persistence

  • Important data must not be lost
  • Memory is too expensive

1.4. Persistence Layer

Dao layer, Service layer, Controller layer

  • A module that does persistence work
  • The layer boundaries are very clear

1.5. Why do I need MyBatis

  • Help developers store data into a database
  • Convenient, simple and easy to use
  • Traditional JDDBC code is so complex that it can be simplified, constrained to the framework, and automated
  • Features:
    • Simple to learn: Small and simple in itself. Without any third party dependence, the simplest installation as long as two JAR files + configuration several SQL mapping files easy to learn, easy to use, through the documentation and source code, can be more fully grasp its design ideas and implementation.
    • Flexibility: MyBatis does not impose any impact on the existing design of the application or database. SQL is written in XML for unified management and optimization. All requirements for operating a database can be met through SQL statements.
    • Decouple SQL from program code: By providing a DAO layer to separate business logic from data access logic, the system design is clearer, easier to maintain, and easier to unit test. Separation of SQL and code improves maintainability.
    • Provides mapping labels to support orM field relational mapping of objects to databases
    • Provides object-relational mapping labels to support object-relational maintenance
    • Provides XML tags to support writing dynamic SQL.

The first Mybatis program

Build environment ==> import Mybaits==> write code ==> test

2.1. Build the environment

  1. Set up database:
CREATE DATABASE `mybatis`;

USE `mybatis-demo`;

CREATE TABLE `USER` (
`id` INT(20) NOT NULL PRIMARY KEY,
`username` VARCHAR(30) DEFAULT NULL,
`password` VARCHAR(30) DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO `USER` (`id`,`username`,`password`) VALUES
(1," zisu ","1234"), (2,"admin","0000"),
(3,"muser","3571")
Copy the code
  • New project

    1. Create a normal Maven project (no templates)
    2. As the parent project, delete SRC
    3. Import dependence
              <! -- mysql -->
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>8.0.25</version>
              </dependency>
              <! -- mybatis -->
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis</artifactId>
                  <version>3.5.7</version>
              </dependency>
              <! -- junit -->
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>4.13.2</version>
                  <scope>test</scope>
              </dependency>
      Copy the code

Create a Module (subModule)

2.2.1. Write mybatis configuration file


      
<! DOCTYPEconfiguration
        PUBLIC "- / / mybatis.org//DTD Config / 3.0 / EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<! Mybatis core configuration file -->
<configuration>
    <environments default="development">
        <environment id="development">
            <! -- Transaction management type JDBC-->
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <! Mysql > select * from 'cj';
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <! Secure connection, code, time zone -->
                <property name="url" value="jdbc:mysql://localhost:3306? mybatis&amp;useSSl=true&amp;userUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=Asia/Shanghai"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>
Copy the code

2.2.2. Write myBatis tool class

public class MybatisUtil {
    private static SqlSessionFactory sqlSessionFactory;
    static{
        try {
            // Get the SqlSessionFactory object from mybatis
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch(IOException e) { e.printStackTrace(); }}//SqlSession contains all the methods needed to execute SQL commands to the database
    public SqlSession getSqlSession(a){
        returnsqlSessionFactory.openSession(); }}Copy the code

2.3. Write code

2.3.1 Entity Classes

public class User {
    
    private int id;
    private String username;
    private String password;

    public User(a) {}public User(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public int getId(a) {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername(a) {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword(a) {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString(a) {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\' ' +
                ", password='" + password + '\' ' +
                '} '; }}Copy the code

2.3.2 Dao interface

public interface UserDao {

    public List<User> getUsers(a);
}
Copy the code

2.3.3 Interface implementation classes

Mybatis is an implementation class that uses XML instead of the DAO interface


      
<! DOCTYPEmapper
        PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sama.dao.UserDao">
    <! -- query statement -->
    <select id="getUsers" resultType="com.sama.pojo.User">
        select * from mybatis.user
    </select>
</mapper>
Copy the code

2.4, tests,

2.4.1 write test classes and test

public class UserDaoTest {

    @Test
    public void test(a){
        //1. Obtain the SqlSession object
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        
        2. Obtain the UserDao object
        //2.1 Method 1: The latest recommendation
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //2.2 Method two, this is the original method is not recommended
        //List<User> users =sqlSession.selectList("com.sama.dao.UserDao.getUsers");
        
        //3. Run the query method
        List<User> users = userDao.getUsers();

        //4. View the query result
        for (User user : users) {
            System.out.println(user);
        }

        / / 5. Close the SqlSessionsqlSession.close();; }}Copy the code

2.4.2, errors,

A wrong

  1. This is an easy binding error to make: the UserDao is not registered with Mapper
  2. What is MapperRegistry? See 4.2 for details
  3. Each mapper.xml needs to be registered in the Mybatis core configuration file

Error 2

  1. Maven common errors, resource filtering problems, can be found in Maven notes
  2. Because maven has more conventions than configuration, there may be problems with our written configuration files that cannot be exported or taken effect

Error of three

  1. This is a header error in mybaits’ mapper. XML file

      
Copy the code
  1. Specific cause: Error in compiling the XML configuration file of MyBatis in IDEA

  2. Reference: www.cnblogs.com/yuqiliu/p/1…

  3. In the character set of the overall project of the new in the idea file character set GBK defaults to form, so all new documents with GBK character format to escape of Chinese characters, can result in errors, may be the two coding format for some special Chinese decoding rules is different, can sometimes errors using each other, but sometimes can’t, This is especially true when writing XML configuration files.

  4. And because MY XML configuration file was written like this, I thought I had already configured the character format of IDEA as UTF-8, but I forgot that I only configured it in the project last time, but not in the global idea, so I stumbled into this hole today. GBK encoding GBK encoding GBK encoding


2.4.3, modify,

  1. Register in mybatis-config.xml
<mappers>
        <mapper resource="com/sam/dao/UserMapper.xml"/>
    </mappers><mappers>
        <mapper resource="com/sam/dao/UserMapper.xml"/>
    </mappers>
Copy the code

  1. Add the build configuration to the pom.xml file
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
        </resource>
    </resources>
</build>
Copy the code

  1. There are two modification methods. The second one is recommended once and for all

    1. Change the XML file header utF-8 to UTF8
    
            
    Copy the code
    1. Configure the encoding format in the IDEA global

2.4.4 Error summary

The following errors may occur

  1. The configuration file is not registered
  2. Binding interface error
  3. Incorrect method name
  4. Incorrect return type
  5. Maven export resource problem

3, add, delete, change and check

3.1, the select

Select, query statement

  • Id: indicates the method name in the namespace
  • ResultType: return value of the Sql statement execution
  • ParameterType: parameterType
  1. Write the interface
public User getUserById(int id);
Copy the code
  1. Write the SQL statement of mapper, the mapping file of the corresponding interface
<! -- query statement -->
<select id="getUsers" resultType="com.sama.pojo.User">
    select * from mybatis.user
</select>
Copy the code

3. The test

@Test
public void getUserById(a){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    User user = userDao.getUserById(1);
    System.out.println(user);
    //close
    sqlSession.close();
}
Copy the code

3.2, the insert

  1. Write the interface
public int addUser(User user);
Copy the code
  1. Write the SQL statement of mapper, the mapping file of the corresponding interface
<! -- Attributes in the object can be fetched directly -->
<insert id="addUser" parameterType="com.sama.pojo.User">
    insert into mybatis.user (id,username,password) values (#{id},#{username},#{password})
</insert>
Copy the code

3. The test

@Test
public void addUser(a){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    int result = userDao.addUser(new User(4."Boy Sue"."jjjj"));
    if(result>0){
        System.out.println("Operation successful");
    }
    // Commit the transaction
    sqlSession.commit();
    sqlSession.close();
}
Copy the code

3.3, the update

The SQL statement

<update id="updateUser" parameterType="com.sama.pojo.User">
    update mybatis.user set username=#{username}, password=#{password} where id=#{id}
</update>
Copy the code

3.4, delete

The SQL statement

<delete id="deleteUserById" parameterType="int">
    delete from mybatis.user where id=#{id}
</delete>
Copy the code

3.5. Pay attention

  • Attention! Add, delete, or change a transaction
  • Attention! SqlSession should be closed in time
  • Attention! Resource binding mapper requires path “/”, not “.”

3.6 universal map

Parameters can be added or modified using map instead of object

  • The XML parameter type is map
  • Fields that need not be modified can be omitted in SQL
  • The field corresponds to the key

The dao interface

public int updateUserForMap(Map<String,Object> map);
Copy the code

The SQL statement

<update id="updateUser" parameterType="map">
    update mybatis.user set username=#{keyUsername} where id=#{id}
</update>
Copy the code

test

@Test
public void updateUserForMap(a){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserDao userDao = sqlSession.getMapper(UserDao.class);
    Map<String,Object> map = new HashMap<>();
    map.put("keyId".3);
    map.put("keyName"."Map");
    int result = userDao.updateUserForMap(map);
    if(result>0){
        System.out.println("Operation successful");
    }
    sqlSession.commit();
    sqlSession.close();
}
Copy the code

3.7. Fuzzy query

  1. When Java code executes, the wildcard % % is passed
List<User> users = userDao.getUsers("% %" li);
Copy the code
  1. Use wildcards in SQL concatenation
select * from mybatis.user where name like "%"#{value}"%"
Copy the code

4. Mybatis core configuration analysis

The MyBatis configuration file contains Settings and property information that will deeply affect MyBatis behavior.

The top-level structure of the configuration document is as follows:

  • Configuration
    • Properties
    • Settings
    • typeAliases
    • typeHandlers
    • objectFactory
    • Plugins
    • Environments
      • Environment (environment variable)
      • transactionManager
        • A dataSource
    • DatabaseIdProvider (Database vendor Identity)
    • Mappers (mapper)

4.1 Environment Configuration

MyBatis can be configured to adapt to a variety of environments, development, test and production environments need to have different configurations; Or you want to use the same SQL mapping across multiple production databases with the same Schema

Although multiple environments can be configured, only one environment can be selected per SqlSessionFactory instance.

4.1.1. Note some key points

  • The environment ID used by default (for example: default=”development”).
  • The environment ID defined by each environment element (for example: ID =”development”).
  • Transaction manager configuration (for example: type=”JDBC”).
  • Data source configuration (for example: type=”POOLED”).

The default environment and environment ID are as their names suggest. The environment can be named as you like, but make sure that the default environment ID matches one of the environment ids.


4.1.2 transactionManager

In MyBatis there are two types of transaction manager (i.e., 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). It closes the connection by default. 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. Such as:
<transactionManager type="MANAGED">
  <property name="closeConnection" value="false"/>
</transactionManager>
Copy the code

4.1.3 dataSource

  • The dataSource element uses the standard JDBC dataSource interface to configure the resources of the JDBC connection object.
  • Most MyBatis applications follow the example in the example to configure the data source. Although the data source configuration is optional, it must be configured if the lazy loading feature is to be enabled.
  • There are three kinds of built-in data types (type = “[UNPOOLED | POOLED | JNDI]”)

4.2, attributes,

These properties can be configured externally and can be dynamically replaced. You can configure these properties either in a typical Java properties file or in a child element of the Properties element.

  1. Configured with the child element of Properties
<properties resource="org/mybatis/example/config.properties">
  <property name="username" value="root"/>
  <property name="password" value="1234"/>
</properties>
<configuration>
    <environments default="development">
        <environment id="development">
            <! -- Transaction management type JDBC-->
            <transactionManager type="JDBC"/>
                <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>
</configuration>
Copy the code

2. Configure using the properties file

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306? mybatis& useSSl=true&userUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username=root
password=1234
Copy the code
<properties resource="db.properties">
</properties>
<configuration>
    <environments default="development">
        <environment id="development">
            <! -- Transaction management type JDBC-->
            <transactionManager type="JDBC"/>
                <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>
</configuration>
Copy the code

Call attributes in XML with ${key}

4.3, set

Set the name describe Valid values The default value
cacheEnabled Globally turn on or off any caches that have been configured in all mapper profiles. true / false true
lazyLoadingEnabled Global switch of lazy loading. When enabled, all associated objects are lazily loaded. The fetchType attribute can be set to override the on/off state of an item in a particular association. true / false false
mapUnderscoreToCamelCase Whether to enable automatic camel name mapping, that is, from the classic database column name A_COLUMN to the classic Java property name aColumn. true / false false
logImpl Specify the specific implementation of logging used by MyBatis. If not specified, it will be automatically found. SLF4J / LOG4J / LOG4J2 / … Is not set
<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
</settings>
Copy the code

4.4 typeAliases

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

  1. Category name annotation mode
@Alias("User")
public class User {... }Copy the code
  1. Category Name XML configuration mode
<typeAliases>
  <typeAlias alias="User" type="com.sama.pojo.User"/>
</typeAliases>
Copy the code
  1. Package alias XML configuration: MyBatis searches for desired Java beans under the package name
<typeAliases>
  <package name="com.sama.pojo"/>
</typeAliases>
Copy the code

4.5 mappers

MapperRegistry: The mapper file that registers the binding to implement the interface

There are four implementations:

<! -- Use a resource reference relative to the classpath -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
Copy the code
<! -- Use fully qualified resource locator (URL) -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
Copy the code
<! Implement the fully qualified class name of the class using the mapper interface
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
Copy the code
<! Register all mapper interface implementations as mapper
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>
Copy the code

Pay attention to is

  • The second approach fully qualified resource locators (urls) are generally not used
  • Third, the four methods can only be used under certain conditions
    • The interface and mapping files must be in the same package
    • The name of the interface and mapping file must be the same
  • The first is recommended

4.6 nouns in a mapping configuration file

Namespace (namespace)

  • The binding corresponds to the Dao interface to implement
  • Namespaces serve two purposes
    • One is to isolate different statements with longer fully qualified names,
    • It also implements the interface binding you saw above.
    • Namespace as shown below
    <! Namespace: bind Dao/Mapper interface -->
    <mapper namespace="com.sama.dao.UserDao">
        <! -- query statement -->
        <select id="getUsers" resultType="com.sama.pojo.User">
            select * from mybatis.user
        </select>
    </mapper>
    Copy the code

Scope and life cycle

Object lifecycle and dependency injection framework

Dependency injection frameworks can create thread-safe, transaction-based SQLSessions and mappers and inject them directly into your beans, so their life cycles can be ignored


4.7.1, the SqlSessionFactoryBuilder is

  • This class can be instantiated, used, and discarded, and is no longer needed once the SqlSessionFactory has been created.
  • So the best scope for SqlSessionFactoryBuilder instances is the method scope (that is, local method variables).
  • You can reuse SqlSessionFactoryBuilder to create multiple instances of SqlSessionFactory, but it’s best not to keep it around all the time to ensure that all XML parsing resources can be freed up for more important things.

4.7.2, SqlSessionFactory

  • Once created, the SqlSessionFactory should persist for the duration of the application, and there is no reason to discard it or recreate another instance.
  • The best practice with SqlSessionFactory is not to create the SqlSessionFactory more than once while the application is running. Rebuilding SqlSessionFactory more than once is considered a code “bad habit.”
  • So the best scope for SqlSessionFactory is the application scope. There are many ways to do this, the easiest is to use singleton or static singleton.

4.7.3, SqlSession

  • Each thread should have its own INSTANCE of SqlSession. An instance of SqlSession is not thread-safe and therefore cannot be shared, so its best scope is the request or method scope.
  • A reference to an SqlSession instance must never be placed in a static domain of a class, or even an instance variable of a class. A reference to an SqlSession instance should also never be placed in any type of managed scope, such as HttpSession in the Servlet framework.
  • If you are currently using a Web framework, consider putting SqlSession in a scope similar to HTTP requests. In other words, each time an HTTP request is received, an SqlSession can be opened, and when a response is returned, it can be closed. The close operation is important, and to ensure that the close operation is performed every time, you should put the close operation ina finally block.
  • The following example is a standard mode to ensure that SqlSession is closed:
    try (SqlSession session = sqlSessionFactory.openSession()) {
      // Your application logic code
    }
    Copy the code
  • Following this usage pattern in all code ensures that all database resources are shut down correctly.

4.7.4. Mapper Instance

  • Mappers are interfaces that bind mapping statements. The instance of the mapper interface is obtained from SqlSession.
  • Although technically speaking, the maximum scope of any mapper instance is the same as the SqlSession from which they are requested. But the method scope is the most appropriate scope for the mapper instance. That is, mapper instances should be retrieved in the methods that call them and then discarded after use.
  • The mapper instance does not need to be explicitly closed. Although keeping the mapper instance in the entire request scope is fine, you will soon find that managing too many resources like SqlSession in this scope can get you too busy.
  • Therefore, it is best to place the mapper in the method scope. As in the following example:
    try (SqlSession session = sqlSessionFactory.openSession()) {
      BlogMapper mapper = session.getMapper(BlogMapper.class);
      // Your application logic code
    }
    Copy the code

A CRUD operation execution flow


SqlSessionFactory relationships with SqlSession and Mapper

Each Mapper here represents a specific business

5. ResultMap

The resultMap element is the most important and powerful element in MyBatis. It frees you from 90% of the JDBC ResultSets data extraction code

5.1. When the attribute name and field name are inconsistent

  1. Change an SQL field to an alias
<select id="selectUsers" resultType="User">
  select
    user_id             as "id",
    user_name           as "userName",
    hashed_password     as "hashedPassword"
  from some_table
  where id = #{id}
</select>
Copy the code
  1. Use the resultMap
  • Configuration of the resultMap
<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>
Copy the code
  • The SQL statement
<select id="selectUsers" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>
Copy the code

5.2. Advanced result Mapping

MyBatis was created with the idea that databases won’t always be what you think or need them to be. We want every database to have a good third normal form or BCNF normal form, but they are not always that way

resultMap

  • Constructor – Used to inject results into a constructor when instantiating a class
    • Idarg-id parameter; Marking the result as an ID can help improve overall performance
    • Arg – an ordinary result that will be injected into the constructor
  • Id – an ID result; Marking the result as an ID can help improve overall performance
  • Result – A normal result injected into a field or JavaBean property
  • Association – an association of a complex type; Many results will be wrapped in this type
    • Nested result maps – the association can be a resultMap element or a reference to another resultMap
  • Collection – A collection of complex types
    • Nested result maps – Collections can be resultMap elements or references to other result maps
  • Discriminator – Uses the result value to determine which resultMap to use
    • Case – Result mapping based on some value
      • Nested result map – Case is also a result map and therefore has the same structure and elements; Or reference other result mappings

6, logs,

6.1 Log Factory

If an exception occurs in a database operation. A log is your best helper when you make a mistake. Sout and DEBUG were used before there was no logging. Now there is a log factory

However, which logging implementation to use in Mybatis is specified in the Settings.

Set the name describe Valid values The default value
logImpl Specify the specific implementation of logging used by MyBatis. If not specified, it will be automatically found. LOG4J / STDOUT_LOGGING / … Is not set

An optional value

  • SLF4J
  • LOG4J master
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING master
  • NO_LOGGING
<settings>
    <! -- Standard log factory implementation -->
    <setting name="logImpl" value="LOG4J"/>
</settings>
Copy the code

Note that the name and value can not be wrong, do not add a space. Must be exactly the same as the official website!

  • This is without adding log console output


  • Use “STDOUT_LOGGING” logging

6.2, Log4j

What is the Log4j

  • Log4j is an open source project of Apache. Using Log4j, you can control the destination of log messages to the console, files, GUI components, even the socket server, NT event loggers, UNIX Syslog daemons, and so on
  • We can also control the output format of each log
  • By defining the level of each log message, we can more carefully control the log generation process.
  • These can be configured flexibly through a configuration file without the need to modify the application code.

The use of Log4j

  1. Guide package
<! -- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
Copy the code
  1. Configure the logging implementation in Mybatis configuration
<settings>
    <setting name="logImpl" value="LOG4J"/>
</settings>
Copy the code
  1. Create log4j.properties in CLASSPATH (just put it in Resources)
Configure the root Logger
log4j.rootLogger  =   [level], appenderName1, appenderName2...
Configure the Appender destination for logging information output
log4j.appender.appenderName  =  fully.qualified.name.of.appender.class 
log4j.appender.appenderName.option1  =  value1 
... 
log4j.appender.appenderName.optionN  =  valueN 
Configure the format of the log message (layout)
log4j.appender.appenderName.layout  =  fully.qualified.name.of.layout.class 
log4j.appender.appenderName.layout.option1  =  value1 
... 
log4j.appender.appenderName.layout.optionN  =  valueN
Copy the code
### set log levels ###
log4j.rootLogger = debug , stdout , D , E
Output to console ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{1}:%L - %m%n
Output to log file ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
Save exception information to a separate file ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
Copy the code
  1. The log object takes the class of the current class

static Logger logger = Logger.getLogger(UserDaoTest.class);

  1. The level of logging
@Test
public void log4jTest(a) {
    logger.info("Info: log4jTest entered");
    logger.debug("Debug: log4jTest entered");
    logger.error("Error: log4jTest entered");
}
Copy the code
  1. Format to explain
  • Log4j log output format:
  • %c Specifies the full name of the class to which the log information belongs
  • The default format is ISO8601. You can also specify a format, for example, % D {YYY-MM-DD HH: MM :ss}. The output is similar to 2020-02-01-17:17:16
  • %f Indicates the name of the class to which the log information belongs
  • %l The occurrence of the output log event is unknown, that is, the line of the class in which the statement that outputs the log information resides
  • %m prints the information specified in the code, such as message in log(message)
  • %n Prints a carriage return newline, “RN” on Windows, “n” on Unix
  • % p output priority, namely the DEBUG, INFO, WARN, ERROR, FATAL. If it is output by a call to debug (), it is DEBUG, and so on
  • %r Indicates the number of milliseconds that elapsed between the application startup and the output of the log message
  • %t Prints the name of the thread that generated the day’s events

So %5p%t-%m%n means: priority thread name of width 5 (filename: line number) – message enter newline

7, paging

Use limit paging

select * from user limit startIndex,pageSize;
select * from userlimit n; # [0,n]
Copy the code