mybatis-plus - MybatisPlusAutoConfiguration


mybatis 的通用maper, 其實有很多, mybatis-plus 算是其中做的比較好的一款了. 這里就來看一下 mybatis-plus 是怎么實現這個通用mapper功能的.

一. BaseMapper

mybatis中 Mapper interface 的時候, 並沒有繼承什么接口. 所以想要什么方法, 得自己添加. 

在mybatis-plus 中, 讓 Mapper interface 繼承了 BaseMapper 接口, 直接的結果, 就是 Mapper.java 多了很多方法:

public interface BaseMapper<T> {
    /**
     * <p>
     * 插入一條記錄
     * </p>
     *
     * @param entity 實體對象
     */
    int insert(T entity);

    /**
     * <p>
     * 根據 ID 刪除
     * </p>
     *
     * @param id 主鍵ID
     */
    int deleteById(Serializable id);

    /**
     * <p>
     * 根據 columnMap 條件,刪除記錄
     * </p>
     *
     * @param columnMap 表字段 map 對象
     */
    int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * <p>
     * 根據 entity 條件,刪除記錄
     * </p>
     *
     * @param queryWrapper 實體對象封裝操作類(可以為 null)
     */
    int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 刪除(根據ID 批量刪除)
     * </p>
     *
     * @param idList 主鍵ID列表(不能為 null 以及 empty)
     */
    int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * <p>
     * 根據 ID 修改
     * </p>
     *
     * @param entity 實體對象
     */
    int updateById(@Param(Constants.ENTITY) T entity);

    /**
     * <p>
     * 根據 whereEntity 條件,更新記錄
     * </p>
     *
     * @param entity        實體對象 (set 條件值,不能為 null)
     * @param updateWrapper 實體對象封裝操作類(可以為 null,里面的 entity 用於生成 where 語句)
     */
    int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

    /**
     * <p>
     * 根據 ID 查詢
     * </p>
     *
     * @param id 主鍵ID
     */
    T selectById(Serializable id);

    /**
     * <p>
     * 查詢(根據ID 批量查詢)
     * </p>
     *
     * @param idList 主鍵ID列表(不能為 null 以及 empty)
     */
    List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

    /**
     * <p>
     * 查詢(根據 columnMap 條件)
     * </p>
     *
     * @param columnMap 表字段 map 對象
     */
    List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

    /**
     * <p>
     * 根據 entity 條件,查詢一條記錄
     * </p>
     *
     * @param queryWrapper 實體對象
     */
    T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 Wrapper 條件,查詢總記錄數
     * </p>
     *
     * @param queryWrapper 實體對象
     */
    Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 entity 條件,查詢全部記錄
     * </p>
     *
     * @param queryWrapper 實體對象封裝操作類(可以為 null)
     */
    List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 Wrapper 條件,查詢全部記錄
     * </p>
     *
     * @param queryWrapper 實體對象封裝操作類(可以為 null)
     */
    List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 Wrapper 條件,查詢全部記錄
     * 注意: 只返回第一個字段的值
     * </p>
     *
     * @param queryWrapper 實體對象封裝操作類(可以為 null)
     */
    List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 entity 條件,查詢全部記錄(並翻頁)
     * </p>
     *
     * @param page         分頁查詢條件(可以為 RowBounds.DEFAULT)
     * @param queryWrapper 實體對象封裝操作類(可以為 null)
     */
    IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * <p>
     * 根據 Wrapper 條件,查詢全部記錄(並翻頁)
     * </p>
     *
     * @param page         分頁查詢條件
     * @param queryWrapper 實體對象封裝操作類
     */
    IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}

 

二. MapperScan

MapperScan這塊, 還是 mybatis 的功能. 對 Mapper.java 進行掃描注冊 : MapperFactoryBean 

具體過程見: MapperScan

 

三. MybatisPlusAutoConfiguration

@Bean
@ConditionalOnMissingBean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
    factory.setDataSource(dataSource);
    factory.setVfs(SpringBootVFS.class);
    if (StringUtils.hasText(this.properties.getConfigLocation())) {
        factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
    }
    applyConfiguration(factory);
    if (this.properties.getConfigurationProperties() != null) {
        factory.setConfigurationProperties(this.properties.getConfigurationProperties());
    }
    if (!ObjectUtils.isEmpty(this.interceptors)) {
        factory.setPlugins(this.interceptors);
    }
    if (this.databaseIdProvider != null) {
        factory.setDatabaseIdProvider(this.databaseIdProvider);
    }
    if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
        factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
    }
    // TODO 自定義枚舉包
    if (StringUtils.hasLength(this.properties.getTypeEnumsPackage())) {
        factory.setTypeEnumsPackage(this.properties.getTypeEnumsPackage());
    }
    if (this.properties.getTypeAliasesSuperType() != null) {
        factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());
    }
    if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
        factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
    }
    if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
        factory.setMapperLocations(this.properties.resolveMapperLocations());
    }
    // TODO 此處必為非 NULL
    GlobalConfig globalConfig = this.properties.getGlobalConfig();
    //注入填充器
    if (this.applicationContext.getBeanNamesForType(MetaObjectHandler.class,
        false, false).length > 0) {
        MetaObjectHandler metaObjectHandler = this.applicationContext.getBean(MetaObjectHandler.class);
        globalConfig.setMetaObjectHandler(metaObjectHandler);
    }
    //注入主鍵生成器
    if (this.applicationContext.getBeanNamesForType(IKeyGenerator.class, false,
        false).length > 0) {
        IKeyGenerator keyGenerator = this.applicationContext.getBean(IKeyGenerator.class);
        globalConfig.getDbConfig().setKeyGenerator(keyGenerator);
    }
    //注入sql注入器
    if (this.applicationContext.getBeanNamesForType(ISqlInjector.class, false,
        false).length > 0) {
        ISqlInjector iSqlInjector = this.applicationContext.getBean(ISqlInjector.class);
        globalConfig.setSqlInjector(iSqlInjector);
    }
    factory.setGlobalConfig(globalConfig);
    return factory.getObject();
}


private void applyConfiguration(MybatisSqlSessionFactoryBean factory) {
    MybatisConfiguration configuration = this.properties.getConfiguration();
    if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) {
        configuration = new MybatisConfiguration();
    }
    if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) {
        for (ConfigurationCustomizer customizer : this.configurationCustomizers) {
            customizer.customize(configuration);
        }
    }
    factory.setConfiguration(configuration);
}


@Bean
@ConditionalOnMissingBean
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
    ExecutorType executorType = this.properties.getExecutorType();
    if (executorType != null) {
        return new SqlSessionTemplate(sqlSessionFactory, executorType);
    } else {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

關鍵類對應表:

mybatis mybatis-plus
SqlSessionFactoryBean
MybatisSqlSessionFactoryBean 
Configuration
MybatisConfiguration
SqlSessionTemplate
SqlSessionTemplate
1. MybatisSqlSessionFactoryBean 並不是 SqlSessionFactoryBean 的繼承類, 他是一個新類. 其中有很多屬性和方法都是從 SqlSessionFactoryBean 中拷貝過來的,然后加了一些東西.
2. MybatisConfiguration 繼承自 Configuration 類, 其中加入了一個非常重要的屬性: 
    /**
     * Mapper 注冊
     */
    public final MybatisMapperRegistry mybatisMapperRegistry = new MybatisMapperRegistry(this);

與之對應的是  Configuration  中的:

protected final MapperRegistry mapperRegistry = new MapperRegistry(this);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM