浅谈Mybatis Plus的BaseMapper的方法是如何注入的

Mybatis Plus的BaseMapper的方法

我们在用的时候经常就是生产自定义的Mapper继承自BaseMapper,然后我们就可以使用了,但是有没想过BaseMapper里的方法是怎么被注入到mybatis里的,也没看到什么xml啊,今天我们就来看看是怎么回事。

6C2E6305-2C08-813F-8A47-09C1D854A18A.png

Mybatis Plus的初始化方法
MybatisPlusAutoConfiguration中的SqlSessionFactory

在创建的时候会创建MybatisSqlSessionFactoryBean,然后设置MybatisConfiguration作为配置类。

B2A0CA2F-6887-F4D6-9A7A-5DEB38D2B57F.png

MybatisConfiguration是继承自Configuration的:

B32622EC-4661-7051-53A6-548028E15D1A.png

自定义了一个MybatisMapperRegistry注册器,后面会用到。

7D93BD6D-CD4A-4086-3332-6FF34C111EF6.png

BaseMapper方法的注入的过程

MybatisSqlSessionFactoryBean的初始化后方法afterPropertiesSet调用buildSqlSessionFactory创建SqlSessionFactory

70B7CE0B-59FE-53FA-34AB-8E094582B850.png

其实就会去解析自定义的mapperxml文件:

3469CCD4-D6A0-F6AB-3CFA-9489792CDE7C.png

B16C77BC-8F0A-25DC-1C87-FAB0E45DAFBC.png

其中有个addMapper的方法,是前面MybatisConfiguration调用的。

3D3A19BC-C4EB-3A5C-A747-3C1C8F63AA79.png

会解析出对应的类型,然后内部调用MybatisMapperRegistry的方法:

9D9BF0E3-C2A9-D8BC-3273-7FFD76954BA9.png

内部最后是MybatisMapperAnnotationBuilder去解析的:

68452184-A241-6DFC-E5D6-A5A1E73B0601.png

里面会进行基本的SQL方法注入:

9C1FF4B1-1662-10D4-3D02-6B824463DD9C.png

CFDDCC53-0A69-B305-4F68-81096E192163.png

完成每个方法的注入:

B7F016DD-7697-8027-0AC7-8249B15029F0.png

注入的实现:

5BC7322F-6984-59F8-4C13-5CBCC5ED2093.png

其实每一个AbstractMethod的子类都会实现自己的injectMappedStatement

CDCAF6A1-F764-CF41-11ED-A88BE81478DC.png

197AE1F1-F24E-F034-D5D8-DA5644CE326C.png

最后会去枚举类SqlMethod中获取对应的枚举,里面就是类似定义在xml中的信息,最后转换为sqlSource再进行封装:

0A9FBF35-2DB1-291E-5AE3-CBA8232C9F80.png

SqlMethod 枚举值:

public enum SqlMethod {
    /**
     * 插入
     */
    INSERT_ONE("insert", "插入一条数据(选择字段插入)", "<script>\nINSERT INTO %s %s VALUES %s\n</script>"),
    UPSERT_ONE("upsert", "Phoenix插入一条数据(选择字段插入)", "<script>\nUPSERT INTO %s %s VALUES %s\n</script>"),

    /**
     * 删除
     */
    DELETE_BY_ID("deleteById", "根据ID 删除一条数据", "<script>\nDELETE FROM %s WHERE %s=#{%s}\n</script>"),
    DELETE_BY_MAP("deleteByMap", "根据columnMap 条件删除记录", "<script>\nDELETE FROM %s %s\n</script>"),
    DELETE("delete", "根据 entity 条件删除记录", "<script>\nDELETE FROM %s %s %s\n</script>"),
    DELETE_BATCH_BY_IDS("deleteBatchIds", "根据ID集合,批量删除数据", "<script>\nDELETE FROM %s WHERE %s IN (%s)\n</script>"),

    /**
     * 逻辑删除
     */
    LOGIC_DELETE_BY_ID("deleteById", "根据ID 逻辑删除一条数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),
    LOGIC_DELETE_BY_MAP("deleteByMap", "根据columnMap 条件逻辑删除记录", "<script>\nUPDATE %s %s %s\n</script>"),
    LOGIC_DELETE("delete", "根据 entity 条件逻辑删除记录", "<script>\nUPDATE %s %s %s %s\n</script>"),
    LOGIC_DELETE_BATCH_BY_IDS("deleteBatchIds", "根据ID集合,批量逻辑删除数据", "<script>\nUPDATE %s %s WHERE %s IN (%s) %s\n</script>"),

    /**
     * 修改
     */
    UPDATE_BY_ID("updateById", "根据ID 选择修改数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),
    UPDATE("update", "根据 whereEntity 条件,更新记录", "<script>\nUPDATE %s %s %s %s\n</script>"),

    /**
     * 逻辑删除 -> 修改
     */
    LOGIC_UPDATE_BY_ID("updateById", "根据ID 修改数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),

    /**
     * 查询
     */
    SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s} %s"),
    SELECT_BY_MAP("selectByMap", "根据columnMap 查询一条数据", "<script>SELECT %s FROM %s %s\n</script>"),
    SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", "<script>SELECT %s FROM %s WHERE %s IN (%s) %s</script>"),
    SELECT_ONE("selectOne", "查询满足条件一条数据", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
    SELECT_COUNT("selectCount", "查询满足条件总记录数", "<script>%s SELECT COUNT(%s) FROM %s %s %s\n</script>"),
    SELECT_LIST("selectList", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
    SELECT_PAGE("selectPage", "查询满足条件所有数据(并翻页)", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
    SELECT_MAPS("selectMaps", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s\n</script>"),
    SELECT_MAPS_PAGE("selectMapsPage", "查询满足条件所有数据(并翻页)", "<script>\n %s SELECT %s FROM %s %s %s\n</script>"),
    SELECT_OBJS("selectObjs", "查询满足条件所有数据", "<script>%s SELECT %s FROM %s %s %s\n</script>");

    private final String method;
    private final String desc;
    private final String sql;

    SqlMethod(String method, String desc, String sql) {
        this.method = method;
        this.desc = desc;
        this.sql = sql;
    }

    public String getMethod() {
        return method;
    }

    public String getDesc() {
        return desc;
    }

    public String getSql() {
        return sql;
    }

}

最终还是调用了MapperBuilderAssistantaddMappedStatement进行注册:

34E6876C-F7CD-7FBF-6553-A4539B7641F2.png

总结
  1. 初始化注入自定义的MybatisConfigurationMybatisMapperRegistry
  2. 解析Mapper类,获取方法对应的AbstractMethod
  3. 调用各自的实现进行去SqlMethod获取对应的枚举,获取到信息后进行注册。

其实就相当于代码里面定义了原本需要再xx.xml定义的数据,直接在代码中获取注入常用的CRUD操作即可。

收藏 (0)
评论列表
正在载入评论列表...
我是有底线的
为您推荐
    暂时没有数据