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);

mybatis-plus - MybatisPlusAutoConfiguration的更多相关文章

  1. MyBatisPlus环境下使用MyBatis的配置类

    通过@Configuration使用MyBatis配置类的资料比较少,大部分都是通过XML的形式.找了好久,最终还是通过官方的文档找到了解决方法:http://www.mybatis.org/spri ...

  2. SpirngBoot整合Mybatis Plus多数据源

    导读 有一个这样子的需求,线上正在跑的业务,由于业务发展需要,需重新开发一套新系统,等新系统开发完成后,需要无缝对接切换,当初具体设计见草图. 添加依赖 <!--lombok--> < ...

  3. mybatis plus框架的@TableField注解不生效问题总结

    一.问题描述 最近遇到一个mybatis plus的问题,@TableField注解不生效,导致查出来的字段反序列化后为空 数据库表结构: CREATE TABLE `client_role` ( ` ...

  4. 【分享】标准springMVC+mybatis项目maven搭建最精简教程

    文章由来:公司有个实习同学需要做毕业设计,不会搭建环境,我就代劳了,顺便分享给刚入门的小伙伴,我是自学的JAVA,所以我懂的.... (大图直接观看显示很模糊,请在图片上点击右键然后在新窗口打开看) ...

  5. Java MyBatis 插入数据库返回主键

    最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记. 类似下面这段代码一样获取插入后的主键 User user = new User ...

  6. [原创]mybatis中整合ehcache缓存框架的使用

    mybatis整合ehcache缓存框架的使用 mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓 ...

  7. 【SSM框架】Spring + Springmvc + Mybatis 基本框架搭建集成教程

    本文将讲解SSM框架的基本搭建集成,并有一个简单demo案例 说明:1.本文暂未使用maven集成,jar包需要手动导入. 2.本文为基础教程,大神切勿见笑. 3.如果对您学习有帮助,欢迎各种转载,注 ...

  8. mybatis plugins实现项目【全局】读写分离

    在之前的文章中讲述过数据库主从同步和通过注解来为部分方法切换数据源实现读写分离 注解实现读写分离: http://www.cnblogs.com/xiaochangwei/p/4961807.html ...

  9. MyBatis基础入门--知识点总结

    对原生态jdbc程序的问题总结 下面是一个传统的jdbc连接oracle数据库的标准代码: public static void main(String[] args) throws Exceptio ...

随机推荐

  1. SqlServer视图查询效率测试

    一.  测试背景开发一个项目,数据库用的是sqlserver.帐号表数据有一两百万,不算大,也不算小.在考虑是否要使用视图,担心效率,百度了下资料,众说纷纭,好吧,实践是最好的证明,那么我们就来测试吧 ...

  2. ARC 064 F-Rotated Palindromes

    题意 问有多少个长度为 \(N\) 且字符集大小为 \(K\) 的字符串可以通过回文串旋转 (把第一个字符移到最后)若干次得到.\(N,K\le 10^9\) 做法 设\(f_i\)为最小周期为\(i ...

  3. redis集群&elasticSearch的认识

    elasticSearch_day01 1. Redis集群 1.1 什么叫集群 多台服务器集中在一起,实现同一业务 1.2 为什么集群 一台服务器不够,需要多台服务器支持,解决高并发,集群往往伴随分 ...

  4. import,export深入理解

    export 最正常: var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export { firstName ...

  5. 吴裕雄--天生自然 R语言开发学习:集成开发环境\工具RStudio的安装与配置

  6. NIM游戏的Python实现

    可执行程序下载: 链接:https://pan.baidu.com/s/1xQedrWRBsqQRZvOe91Rvng 提取码:goi9 Nim游戏是博弈论中最经典的模型(之一),它又有着十分简单的规 ...

  7. Python3标准库:array数组

    1. array数组 array模块定义了一个序列数据结构,看起来与list很相似,只不过所有成员都必须是相同的基本类型.支持的类型包括所有数值类型或其他固定大小的基本类型(如字节). 代码 类型 最 ...

  8. python之三目运算符的替代品?

    # 不知曾几何时,你是否也觉得Python的三目运算写起来很麻烦呢?(没有过) # 比如: a, b = 3, 4 c = a if a > b else b d = a if a < b ...

  9. Spring IoC Container源码分析(二)-bean初始化流程

    准备 Person实例 @Data public class Person { private String name; private int age; } xml bean配置 <?xml ...

  10. STM32CubeMX自建MDK工程的基本步骤

    根据需要调节各总线频率 最下方选项,√去掉,不用实时更新库,选择自己库所在路径就好. 点击左侧, 选择"Code Generator", 选择.c 和 .h文件不分开 最后,点击& ...