SoFunction
Updated on 2025-04-14

MyBatis-Plus is based on MyBatis encapsulation. Process steps of BaseMapper

introduction

MyBatis-Plus (MP for short) is an enhanced framework for MyBatis throughBaseMapperProvides general CRUD operations, greatly improving development efficiency. In order to understand its encapsulation mechanism more thoroughly, this article will adopt the thinking of link tracing, start from the developer calling the interface, and gradually penetrate into the core implementation of MyBatis-Plus, and analyze how it completes the encapsulation of BaseMapper based on MyBatis.

1. Start from the call: BaseMapper usage scenario

Suppose we have a simple entity classUserAnd the corresponding Mapper interface:

@TableName("t_user")
public class User {
    @TableId
    private Long id;
    private String name;
    private Integer age;
    // getter and setter omitted}

public interface UserMapper extends BaseMapper<User> {
}

The developer just needs to call this:

UserMapper userMapper = ();
User user = (1L);

On the surface,selectByIdyesBaseMapperThe method provided, but how is it implemented behind it? Let's follow the call link step by step.

2. Link tracking: from interface call to proxy execution

1. Get the Mapper proxy object

When called()When MyBatis'sSqlSessionWill entrust it toConfigurationofgetMappermethod:

// MyBatis: 
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    return (type, sqlSession);
}

HeremapperRegistryIt's from MyBatisMapperRegistryClass, but replaced in MyBatis-Plus withMybatisMapperRegistry. Link to the custom implementation of MyBatis-Plus:

// MyBatis-Plus: 
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) (type);
    if (mapperProxyFactory == null) {
        throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    }
    return (sqlSession);
}
  • Key points: MyBatis-Plus rewrittenMapperRegistryand all inheritances are scanned at startupBaseMapperRegister the interface toknownMappersmiddle.
  • Agent GenerationnewInstanceMethod created aMapperProxyObject, this is the implementation of JDK dynamic proxy.

2. Method call intercept

When called(1L)When the proxy objectMapperProxyofinvokeThe method is triggered:

// MyBatis-Plus: 
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    if ((())) {
        return (this, args);
    }
    MybatisMapperMethod mapperMethod = cachedMapperMethod(method);
    return (sqlSession, args);
}
  • Link forkcachedMapperMethodWill cache according to the method signature and return aMybatisMapperMethodObject.
  • Execution LogicexecuteThe method determines the specific execution path based on the method name and parameters.

forselectById, link entry

// MyBatis-Plus: 
public Object execute(SqlSession sqlSession, Object[] args) {
    if ( == ()) {
        if (().isAssignableFrom()) {
            return ((), args);
        }
        return ((), args[0]);
    }
    // Other types such as INSERT, UPDATE, etc.}
  • Key points()Returns a globally unique SQL ID, e.g.
  • Execute SQL: The final call to MyBatisselectOneMethods execute query.

3. SQL injection: The implementation source of the BaseMapper method

The question is:selectByIdWhere does SQL come from? The answer lies in the SQL injection mechanism of MyBatis-Plus.

1. SQL injection at startup

MyBatis-Plus is passed when the Spring container is initializedMapperScannerConfigurerScan the Mapper interface and callISqlInjectorInject universal SQL:

// MyBatis-Plus: 
public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
    List<AbstractMethod> methodList = getMethodList(mapperClass);
    for (AbstractMethod method : methodList) {
        (builderAssistant, mapperClass);
    }
}
  • Method ListgetMethodListreturnBaseMapperAll methods defined in  (e.g.selectByIdinsertetc.) implementation classes, for exampleSelectById
  • Injection process:bySelectByIdAs an example:
// MyBatis-Plus: 
public void injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
    String sql = ("<script>SELECT %s FROM %s WHERE %s = #{id}</script>",
        sqlSelectColumns(), (), ());
    SqlSource sqlSource = (configuration, sql, modelClass);
    addSelectMappedStatement(mapperClass, "selectById", sqlSource, modelClass, tableInfo);
}
  • SQL Generation:according toTableInfo(Resolve entity class through reflection) Dynamic generationSELECT * FROM t_user WHERE id = #{id}
  • register: Will be generatedMappedStatementRegistered to MyBatisConfigurationmiddle.

2. The role of TableInfo

TableInfois the core metadata class of MyBatis-Plus, throughTableInfoHelperResolve entity classes at startup:

  • @TableName("t_user")→ Table namet_user
  • @TableId→ Primary Key Fieldid
  • Field Mapping → Automatic Inferencenameageetc.

This information provides the basic data for SQL injection.

4. Link summary: the entire process from call to execution

  • Developer calls(1L)
  • Agent interception
  • SQL execution→ MyBatis performs preinjectionMappedStatement
  • Result Mapping: MyBatis maps query results toUserObject returns.

Support behind it:

  • At startup:Scan Mapper → Inject Universal SQL → RegisterMappedStatement
  • Runtime: Dynamic proxy → Method routing → SQL execution.

5. Collaboration and enhancement with MyBatis

  • Multiplex MyBatis: Dynamic proxy,SqlSessionCore mechanisms such as , result mapping are completely inherited from MyBatis.
  • Enhancement Point

    SQL Automation:passISqlInjectorInject universal SQL.

    Metadata managementTableInfoImplement automatic mapping of entities and tables.

    Conditional structureWrapperExtended dynamic query capabilities.

6. Conclusion

MyBatis-Plus encapsulation of BaseMapper is a clever extension of the MyBatis dynamic proxy and SQL execution framework. It implements zero configuration usage of universal CRUD through SQL injection at startup and proxy interception at runtime. Link tracking shows that this design not only retains the flexibility of MyBatis, but also greatly improves development efficiency through automation, which can be regarded as a "perfect completion" of MyBatis.

The above is the detailed content of the process steps of MyBatis-Plus based on MyBatis encapsulation BaseMapper. For more information about MyBatis-Plus encapsulation BaseMapper, please follow my other related articles!