Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.

It mainly recorded the knowledge related to the development of Spring Boot integrated Mybatis database layer

1 Introduction to Java EE Layered Architecture

Java EE architecture divides the system into the following: Model, Data Access Object (Dao), Business logic (Service), Controller (Controller), View (View).

  • The Model layer (Model) is also known as the Domain Object layer. The implementation of business logic depends on the business domain model. It consists mainly of a series of POJOs.
  • Data Access Object (Dao) layer, which provides CRUD operations for mapping domain objects in the Model layer to database tables.
  • The Business logic layer (Service) uses CRUD interfaces provided by Model objects and Dao to realize various functions.
  • The Controller layer, which provides controllers that intercept and invoke the Service layer’s interface to process user requests and send the results to the View layer.
  • The View layer consists of a series of viewmodel pages.

2 introduction of Mybatis

1 Mybatis framework

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.

IBatis comes from the combination of “Internet” and “Abatis”. IBatis is a Java-based persistence layer framework that includes SQL Maps and Data Access Objects(DAO). It supports custom SQL, stored procedures, and advanced mapping. You can avoid almost all of the JDBC code and manual parameter setting and result set fetching.

Mybatis can use XML configuration and annotation to configure and map native information. It can map interface and Java POJO into records in the database. It is widely used because of its simple and flexible characteristics.

Hibernate, the earliest ORM framework (object-relational mapping), provides a full set of mapping mechanism from POJO to database tables. As a fully automated mapping, only the corresponding POJO objects need to be defined to achieve the operation of the database.

Hibernate is not applicable in the following scenarios:

  • For security reasons, only specific SQL data can be provided externally, and the database table structure must be kept secret.
  • The system has a large amount of data processing and strict performance requirements. SQL statements need to be optimized.

Mybatis is a semi-automated ORM implementation compared with Hibernate and other fully automated frameworks. Mybatis only resolves the mapping relationship between POJO and SQL. Specific SQL statements need to be completed by programmers themselves. Then Mybatis maps parameters required by SQL and returned result fields to the specified POJO by mapping configuration files.

2 Mybatis framework composition

1 the interface layer

Mybatis encapsulates the access to the database, and puts the session and transaction control of the database into the SqlSession object.

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
Copy the code

mybatis-config.xml


      
<! DOCTYPEconfiguration
        PUBLIC "- / / mybatis.org//DTD Config / 3.0 / EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <! External properties file -->
    <properties resource="jdbc.properties"></properties>

    <typeAliases>
        <typeAlias alias="user" type="com.cf.entity.User"/>
    </typeAliases>

<! -- <plugins> <plugin interceptor=""></plugin> </plugins>-->
    
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/cf/entity/UserMapper.xml"/>
    </mappers>
</configuration>
Copy the code

UserMapper

public interface UserMapper {

// @Select("select * from USER where id=#{id}")
    User selectOne(Integer id);
}
Copy the code

The Test class

    public static void main(String[] args) throws IOException {
        // MyBatis configuration file
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // Create the sqlSessionFactory object
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // Open a session
        SqlSession session = sqlSessionFactory.openSession();
        User user;
        try {
            // Perform the select operation
            user = (User) session.selectOne("com.cf.entity.UserMapper.selectOne".1);
        } finally {
            // Close the session
            session.close();
        }
        System.out.println(user);
    }
Copy the code

SqlSessionFactory, SqlSession is the core of the Mybatis interface layer class, especially the SqlSession it implements the commonly used API for database operations, specific source visible org. Apache. The ibatis. The session.

SqlSession interface defines the basic CRUD operations to the database, including the select, update, insert, delete, etc., as well as the database transaction rollback rollback and transaction commit a commit operation, for the database connection, the Configuration Configuration, the cache Mapper operation API.

Configuration is the core Configuration class in Mybatis, which defines all the attributes that need to be configured for the database. The Configuration object corresponds to the DefaultSqlSessionFactory one by one, that is, the Configuration object is globally unique in all SqlSession scopes derived from a DefaultSqlSessionFactory. The interface SqlSession also defines the getConfiguration method, used to obtain the Configuration object, that is, we can constantly use the Configuration file, but also can dynamically configure the Configuration property in the code.

2 data processing layer

When the project starts,Mybatis will parse the following files:

  • Sqlmapconfig.xml (or using Java Config annotations)
  • Mapper.xml(or use annotations directly on interface methods)

Sqlmapconfig.xml is parsed in XMLConfigBuilder.

Mapper. XML is resolved in the XMLMapperBuilder, including XMLMapperBuilder on the interpretation of the Statement (SELECT, INSERT, UPDATE, DELETE tags) is done by XMLStatementBuilder, The core parsing code is in the parseStatementNode method.

Mybatis execution flow chart

3 Infrastructure layer

The infrastructure layer contains modules for logging, IO, reflection, exceptions, caching, data sources & connection pooling, transaction management, type mapping, and so on.

1 log

Log4j, Log4j2,Apache Commons Log, Java. Util. Logging, slf4j, stdout (the console), and provide the corresponding adapter. (see the source code org. Apache. Ibatis. Logging package)

Common logging framework with an average of 9 kinds of Log level, that is All, FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE, OFF the Mybatis unity to 4 kinds, namely trace, debug, warn, error.

2 IO

Mybatis I/O contains the following functions:

  • API for reading resource files
  • Encapsulate the ClassLoader and load order required by Mybatis itself

3 the reflection

Mybatis, a lot of scenarios using reflection, including parameter mapping process, the results map processing, read the Class metadata, reflection calls get/set, etc. (see the source code org. Apache. Ibatis. Reflection package)

4 abnormal

Mybatis in exception handling is simple. (see source code org. Apache. Ibatis. Exceptions), one common exception is thrown: org. Apache. Ibatis. Exceptions. PersistenceException

5 the cache

There are two kinds of cache in Mybatis: level 1 cache and level 2 cache. Including the default cache is open, org. Apache. Ibatis. Cache. Impl. PerpetualCache HashMap is level 1 cache content in the object. When flushCache is set to true, it flushes the cache every time, rereading the database and writing to the cache every time. When flushCache is set to false, it does not flush the cache every time, that is, it fetches data directly from the cache the second time.

Mybatis level2 cache, you can use the default built-in, can also by implementing org. Apache. Ibatis. Cache. The cache interface customization.

6 Data source and connection pool

Mybatis data sources and connection pool (source code in the org. Apache. Ibatis. The datasource package), including PooledDataSource implementation class contains the maximum number of connections, the largest number of idle connections, take out the longest time, when the connection is not enough wait time, etc.

  public class PooledDataSource implements DataSource {...// OPTIONAL CONFIGURATION FIELDS
  // Maximum number of active connections
  protected int poolMaximumActiveConnections = 10;
  // Maximum number of idle connections
  protected int poolMaximumIdleConnections = 5;
  // Maximum check time
  protected int poolMaximumCheckoutTime = 20000;
  // Wait time
  protected int poolTimeToWait = 20000;
  // Connection error tolerance
  protected int poolMaximumLocalBadConnectionTolerance = 3;
  protected String poolPingQuery = "NO PING QUERY SET";
  protected boolean poolPingEnabled;
  protected int poolPingConnectionsNotUsedFor;

  private intexpectedConnectionTypeCode; . }Copy the code

7 the transaction

Mybatis in transaction processing, org. Apache. Ibatis. Session. TransactionIsolationLevel object defines the isolation level:

public enum TransactionIsolationLevel {
    / / no transaction
  NONE(Connection.TRANSACTION_NONE),
    // Read submitted
  READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED),
    // Read uncommitted
  READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED),
    // Repeatable
  REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ),
    / / read sequence
  SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE);

  private final int level;

  TransactionIsolationLevel(int level) {
    this.level = level;
  }

  public int getLevel(a) {
    returnlevel; }}Copy the code

Mybatis transactions do not support embedded transactions, and because transactions are in the persistence layer, Spring is often used in development to manage the isolation of transactions.

8 Type Mapping

Mybatis type mapping (source code in org.apache.ibatis. Type package). By org. Apache. Ibatis. Type. TypeAliasRegistry classes to register and maintain with Java basic types of mapping.

public class TypeAliasRegistry {

    // Store a HashMap of type mappings
  private finalMap<String, Class<? >> TYPE_ALIASES =new HashMap<>();

  public TypeAliasRegistry(a) {
      / / type String
    registerAlias("string", String.class);
	  // Basic type of packaging type
    registerAlias("byte", Byte.class);
    registerAlias("long", Long.class);
    registerAlias("short", Short.class);
    registerAlias("int", Integer.class);
    registerAlias("integer", Integer.class);
    registerAlias("double", Double.class);
    registerAlias("float", Float.class);
    registerAlias("boolean", Boolean.class);
	  // The wrapper array type of the primitive type
    registerAlias("byte[]", Byte[].class);
    registerAlias("long[]", Long[].class);
    registerAlias("short[]", Short[].class);
    registerAlias("int[]", Integer[].class);
    registerAlias("integer[]", Integer[].class);
    registerAlias("double[]", Double[].class);
    registerAlias("float[]", Float[].class);
    registerAlias("boolean[]", Boolean[].class);
	  // Basic type
    registerAlias("_byte".byte.class);
    registerAlias("_long".long.class);
    registerAlias("_short".short.class);
    registerAlias("_int".int.class);
    registerAlias("_integer".int.class);
    registerAlias("_double".double.class);
    registerAlias("_float".float.class);
    registerAlias("_boolean".boolean.class);
	  // Basic array type
    registerAlias("_byte[]".byte[].class);
    registerAlias("_long[]".long[].class);
    registerAlias("_short[]".short[].class);
    registerAlias("_int[]".int[].class);
    registerAlias("_integer[]".int[].class);
    registerAlias("_double[]".double[].class);
    registerAlias("_float[]".float[].class);
    registerAlias("_boolean[]".boolean[].class);
	  // Date, decimal, large integer, object class and other built-in types
    registerAlias("date", Date.class);
    registerAlias("decimal", BigDecimal.class);
    registerAlias("bigdecimal", BigDecimal.class);
    registerAlias("biginteger", BigInteger.class);
    registerAlias("object", Object.class);
 	  // Date, decimal, large integer, object class and other built-in types of arrays
    registerAlias("date[]", Date[].class);
    registerAlias("decimal[]", BigDecimal[].class);
    registerAlias("bigdecimal[]", BigDecimal[].class);
    registerAlias("biginteger[]", BigInteger[].class);
    registerAlias("object[]", Object[].class);
	  // Basic collection class type
    registerAlias("map", Map.class);
    registerAlias("hashmap", HashMap.class);
    registerAlias("list", List.class);
    registerAlias("arraylist", ArrayList.class);
    registerAlias("collection", Collection.class);
    registerAlias("iterator", Iterator.class);
      // Result set type
    registerAlias("ResultSet", ResultSet.class);
  }

Copy the code