# mybatisDemo **Repository Path**: baiqy/mybatisDemo ## Basic Information - **Project Name**: mybatisDemo - **Description**: No description available - **Primary Language**: Java - **License**: BSD-3-Clause - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 1 - **Created**: 2020-12-07 - **Last Updated**: 2025-09-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Mybatis ## 概论: - Mybatis:Mybatis SQL Mapper Framework for Java(https://github.com/mybatis/mybatis-3) - Mybatis-Spring:Mybatis Spring Adapter(https://github.com/mybatis/spring)Mybatis作者自己写的 - Mybatis3文档:https://mybatis.org/mybatis-3/zh/index.html - Mybatis Plus文档:https://baomidou.com/ - Mybatis解决了什么问题?为编程提供了哪些便利? - Mybatis在底层默默实现了哪些功能?实现这些功能依据的具体技术有哪些? ## 1、Mybatis与JPA对比 - Mybatis优势: - sql语句可以自由控制,更灵活,性能更高 - sql与代码分离,易于阅读维护 - 提供XML标签,支持编写动态sql语句 - JPA优势: - JPA移植性比较好(JPQL) - 提供了很多CRUD方法,开发效率高 - 对象化程度高 - Mybatis劣势: - 简单的CRUD也要写SQL - XML中有大量SQL维护 - Mybatis自身功能有限,但支持Plugin(物理分页都没有实现,依靠插件每次会生产大量代码) ## 2、MyBatis-Plus: - 简介: mybatis增强工具,只做增强,不做改变。mps分为:core、generator、annotation、extension、mybatis-plus-boot-starter等。在mybatis启动xml和注解注入之后,反射分析实体,注入底层容器。注入之前会判断是否有一样的方法。注入时机是容器启动时,所以使用时无额外性能损耗。 - 特性: - 无侵入、损耗小、强大的CRUD操作 - 支持Lambda形式调用、支持多种数据库 - 支持主键自动生成、支持ActiveRecord模式 - 支持自定义全局通用操作、支持关键词自动转义 - 内置代码生成器、内置分页插件、内置性能分析插件 - 内置全局拦截插件、内置sql注入剥离器,有效的防止注入攻击 - 常用实体类注解: - @TableName、@TableId、@TableField - 排除非表字段的方式: - 使用transient关键字进行修饰,意味着该字段将不参与序列化。禁止使用。我们系统中有使用@Transient注解的,不推荐使用。 - 使用static关键字进行修饰,lombok不会生成get、set方法,所有类共一份。禁止使用。 - @TableField(exist=false),推荐使用 - 条件构造器lambdaQueryWrapper中常用方法: ![img](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy8xNjg4NTQyNy0wMjc0NmFmZmQ4ODFmNWU3LnBuZw?x-oss-process=image/format,png) ## 3、Spring和Mybatis整合核心源码分析 1. Spring核心源码分析 - 根据配置(xml、注解)创建BeanDefinition(beanId、beanClass) - 根据BeanDefinition实例化具体的bean对象 - 启动Spring容器:ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); 2. 什么是FactoryBean,什么是BeanFactory? FactoryBean接口通过getobject()方法来获取对象实例,是工厂bean; BeanFactory是spring 容器; 3. 什么是BeanPostProcessor?什么是BeanFactoryPostProcessor? BeanPostProcessor是spring的拓展接口,初始化bean对象之前、之后调用两个方法。 BeanFactoryPostProcessor是spring容器注册BeanDefinition时,用来干预bean definitions的行为。 4. Mapper接口如何扫描出来的? classForName(String):通过字符串获取对象;newInstance():通过Class获取对象 扫描路径四种配置形式和顺序:package,resource,url,class 5. Mybatis有三种执行器:SIMPLE, REUSE, BATCH;默认是SIMPLE 6. Mybatis一级缓存:默认开启 ## 4、优势: - sql语句可以自由控制,更灵活,性能更高 - sql与代码分离,易于阅读维护 - 提供XML标签,支持编写动态sql语句 ## 5、分页: 1. 新增config类,新增PaginationInterceptor创建方法; 2. BaseMapper中,selectPage()和selectMapsPage()方法; 3. IPage接口(BaseMapper中selectPage()和selectMapsPage()) ## 6、ActiveRecord模式: 1. 概念: 活动记录,一种领域模型模式,一个模型类对应关系型数据库中的一个表,一个实例对应一行数据库记录。其实就是通过对象进行数据库操作。 2. 实现条件 1. 类继承Model<自身类>,@EqualsAndHashCode(callSuper = false) 2. 其对应的Mapper继承BaseMapper 3. 自身调用实现很多操作。 ## 7、主键策略: 1. 局部: - AUTO:自增 - NONE:未设置(根据全局的) - INPUT:用户自身维护 以下是当ID为空,才自动填充。 - ID_WORKER:默认的全局策略,雪花算法(过时) - UUID:全局唯一ID(过时) - ID_WORKER_STR:字符串类型(过时) - ASSIGN_ID:雪花算法(3.3.0) - ASSIGN_UUID:全局唯一ID 2. 全局: global-config: db-config: id-type: assign_id ## 8、通用service 1. 业务service extends IService<业务实体> 2. 业务serviceImpl extends ServiceImpl<业务Mapper, 业务实体> implements 业务Service 3. ServiceImpl已替业务serviceImpl实现了IService的方法 ## 9、自动填充 1. 实体类属性增加注解@TableField(fill = FieldFill.UPDATE) 2. 新增@Component实现MetaObjectHandler的两个方法 3. 判断实体是否存在该属性:metaObject.hasSetter(属性名称) 4. 获取实体属性值:getFieldValByName(属性名称, metaObject) 5. 自动填充方法:strictInsertFill、strictUpdateFill ## 10、乐观锁(多读场景) 1. 仅支持 `updateById(id)` 与 `update(entity, wrapper)` 方法 2. 加载配置: ```java // 注册乐观锁和分页插件(新版:3.4.0) @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); // DbType:数据库类型(根据类型获取应使用的分页方言) // 分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } ``` ## 11、性能分析插件 1. config中新增全局Bean:PerformanceInterceptor(3.3.0以后被p6spy取缔了),可设置format,maxTime 2. 标识只在测试环境:@Profile({"dev", "test"}) 3. 运行时设置参数:-Dspring.profiles.active=dev ## 12、多租户SQL解析器: - 概念: 一种软件架构技术,实现在多用户环境下共用相同的系统,确保各用户数据的隔离性。 - 三种技术方案 - 独立数据库:易于个性化扩展设计,易于恢复数据;安装数据库较多。 - 共享数据库,独立schame:为安全性较高的用户提供了逻辑数据隔离,每个数据库支持更多的多用户;恢复数据困难。 - 共享数据库、schame、表:根据租户id来区分,维护和开销最低,支持最多用户;隔离级别最低,安全性最低,备份恢复困难。 - 实现: 多租户数据SQL解析部分,因为拦截时机的问题,所以依赖mps分页插件,需要在分页插件中设置解析器。 1. implements TenantLineHandler 2. 多租户信息(session、静态变量、配置文件):getTenantId() 3. 多租户字段:getTenantIdColumn() 4. 多租户忽略表:ignoreTable(String tableName) 5. 多租户忽略SQL:@SqlParser(filter = true) ## 13、SQL注入器 - 实现步骤: 1. 创建定义方法的类(extends AbstractMethod) 2. 创建注入器(extends DefaultSqlInjector) 3. 在Mapper中加入自定义方法(加载父类BaseMapper方法:super.getMethodList(mapperClass)) - 选装件 - 批量新增数据,自选字段insert(InsertBatchSomeColumn) - 根据Id逻辑删除数据,并带字段填充功能(LogicDeleteByIdWithFill) - 根据id固定的更新某些字段,除了逻辑删除字段(AlwaysUpdateSomeColumnById) ## 14、通用枚举 - 枚举类 implements IEnum - 实体类中才用枚举类型:private SexEnum sex;