# StudyMybatisPlus **Repository Path**: yang1yu/study-mybatis-plus ## Basic Information - **Project Name**: StudyMybatisPlus - **Description**: record study of mybatis-plus - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-08-16 - **Last Updated**: 2022-09-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: mybatis-plus ## README ## Mybatis-Plus ### 1.Mybatis-Plus简介 ​ [MyBatis-Plus](https://github.com/baomidou/mybatis-plus)(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 #### 1.1 Mybatis-Plus特性 - **无侵入**:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 - **损耗小**:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 - **强大的 CRUD 操作**:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 - **支持 Lambda 形式调用**:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错 - **支持主键自动生成**:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题 - **支持 ActiveRecord 模式**:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作 - **支持自定义全局通用操作**:支持全局通用方法注入( Write once, use anywhere ) - **内置代码生成器**:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用 - **内置分页插件**:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询 - **分页插件支持多种数据库**:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库 - **内置全局拦截插件**:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作 #### 1.2 框架结构 ![1660636547322](README.assets/1660636547322.png) #### 1.3 快速开始 ​ 直接使用idea创建mybatis的项目,再将mybatis-plus的依赖添加到pom.xml文件中即可。https://mvnrepository.com/ ```xml com.baomidou mybatis-plus-boot-starter 3.5.1 ``` #### 1.4 配置 ```yaml spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost/mybatis_plus?useSSL=false username: root password: yang1yu mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl ``` #### 1.5 注解 ```java @TableName 表名注解,表示实体类对应的表 @TableId 主键注解,实体类主键字段 ``` #### 1.6 Mybatis-plus的使用 ##### 继承BaseMapper ```java public interface UserMapper extends BaseMapper { } ``` #### 1.7 通用Service Iservice比BaseMapper做的事情更多一些,实现方式,创建User Service 继承IService并且UserServiceImpl继承BaseMapper,实现UserService接口 UserService.java ```java public interface UserService extends IService { } ``` UserServiceImpl.java 在实现类中添加@Service ```java @Service public class UserServiceImpl extends ServiceImpl implements UserService { } ``` ##### 通用Servcice主要的功能 1. 查询记录的条数(count) 2. 批量插入(savebatch) #### 1.8 常用注解 - @TableName - @TableId type属性: - @TabelField 数据库中使用user_name但是Java代码中使用的是驼峰命名mybatis-plus可以直接转换过来 - @TableLogic 逻辑删除 在需要进行逻辑删除的字段上面添加注解,进行逻辑删除的时候会自动将添加注解的字段改为1(0 存在 1删除),同时在查询的时候是不能查找到逻辑删除的字段 #### 1.9 雪花算法 ##### 背景:应对数据规模的增长 ##### 数据库分表 ### 2. 条件构造器 ![1660638342018](README.assets/1660638342018.png) Wrapper:条件构造抽象类,最顶端父类 - AbstractWrapper:用于查询条件封装,生成sql的where条件 - QueryWrapper:查询条件封装 - UpdateWrapper:update条件查询 - AbstractLabmbdaWrapper:使用Lambda语法 - LambdaQueryWrapper:用于Lambda语法是u用的查询Wrapper - LambdaUpdateWrapper:Lambda更新封装Wrapper 在查询中使用QueryWrapper在更新中使用UpdateWrapper ##### 条件优先级 使用lambda表达式,lambda表达式中的的条件优先执行 ```java UpdateWrapper userUpdateWrapper = new UpdateWrapper<>(); userUpdateWrapper.like("name","yang") .and(i->i.gt("age",20).or().isNull("email")); ``` ##### 组装select字句 ​ 选择可以自定义查询的字段 ```java QueryWrapper userQueryWrapper = new QueryWrapper<>(); userQueryWrapper.select("id","name","age"); ``` ##### 组装子查询 关键字为in ```java //组装出来的sql语句为:select id from user where id in (select * from user where id <= 100) QueryWrapper userQueryWrapper = new QueryWrapper<>(); userQueryWrapper.inSql("id","select id from user where id <= 100"); List users = userMapper.selectList(userQueryWrapper); ``` ##### UpdateWrapper UpdateWrapper可以设置条件和修改的数据 ```java void testUpdateWrapper(){ //UpdateWrapper可以设置条件和修改的数据 UpdateWrapper userUpdateWrapper = new UpdateWrapper<>(); userUpdateWrapper.like("name","yang1yu") .isNotNull("email"); userUpdateWrapper.set("name","UpdateWrapperSet").set("email","UpdateWrapperSet@test.com"); int update = userMapper.update(null, userUpdateWrapper); System.out.println("update:" + update); } ``` ##### 实际开发中的小技巧 在开发过程中往往会对传进来的参数进行判断,这个使用可以使用condition来对条件进行判断 ```java void testCondition(){ String name = "yang2yu"; QueryWrapper userQueryWrapper = new QueryWrapper<>(); //这里就是condition条件的判断,如果不符合条件就不会添加这个条件到sql中 userQueryWrapper.like(StringUtils.isNotBlank(name),"name",name) .isNotNull("email"); List users = userMapper.selectList(userQueryWrapper); for (User user : users) { System.out.println(user); } } ``` ### 3. 插件 #### 分页插件 创建一个配置类,一般有配置类的话,其他的注解也全部写入配置类中。 ```java @Configuration @MapperScan("com.yy.studymybatisplus.mapper") public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } } ``` UserMapper.xml ```xml ``` #### 乐观锁 ```sql CREATE TABLE t_product ( id BIGINT(20) NOT NULL COMMENT '主键ID', NAME VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称', price INT(11) DEFAULT 0 COMMENT '价格', VERSION INT(11) DEFAULT 0 COMMENT '乐观锁版本号', PRIMARY KEY (id) ); INSERT INTO t_product (id, NAME, price) VALUES (1, '外星人笔记本', 100); ``` 创建实体类: ```java import lombok.Data; @Data public class Product { private Long id; private String name; private Integer price; private Integer version; } ``` ##### 乐观锁的实现流程 取出记录时,获取当前version 更新时,version+1,如果where语句中的version不同,则更新失败。 需要在config/MybatisPlusConfig中添加乐观锁插件 ```java //添加乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); ``` ### 4. 枚举类型 表中的有些字段值是固定的,例如性别(男或女),此时我们可以使用MyBatis-Plus的通用枚举 来实现 在数据库中一般使用integer类型来标识,然后数字代表一个,在这里使用性别(1 代表 男性 2 代表女性) 创建一个枚举类型 ```java @Getter public enum SexEnum { MALE(1,"男"), FEMALE(2,"女"); /** * 添加注解 * 使得mybatis-plus标识为一个枚举类型, * mybatis-plus通过有注解的将字符串转换成integer类型放入数据库中 */ @EnumValue private Integer sex; private String sexName; SexEnum(Integer sex, String sexName) { this.sex = sex; this.sexName = sexName; } ``` User 实体类为: ```java public class User { private Long id; private String name; private Integer age; private String email; //mybatis-plus可以自动将数据库中的 is_delete 转换成isDelete //添加逻辑删除字段 @TableLogic private Integer isDelete; //设置性别为枚举类型 private SexEnum sex; } ``` 在设置完枚举类型和添加对应的注解之后,还需要在配置文件中添加对应的枚举扫描: ```yaml mybatis-plus: configuration: #设置日志,可以在控制台中看到所有的Sql语句 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #配置类型别名 默认别名为类名 不区分大小写 type-aliases-package: com.yy.studymybatisplus.entity.User type-enums-package: com.yy.studymybatisplus.enums ``` 测试类: ```java @Test void test(){ User user = new User(); user.setEmail("863386791@qq.com"); user.setAge(18); user.setSex(SexEnum.MALE); user.setName("SexEnums"); int insert = userMapper.insert(user); System.out.println("insert:" + insert); } 对应的sql语句为: Preparing: INSERT INTO user ( id, name, age, email, sex ) VALUES ( ?, ?, ?, ?, ? ) Parameters: 1561904188847845378(Long), SexEnums(String), 18(Integer), 863386791@qq.com(String), 1(Integer) ``` ### 5. 代码生成器 (和mybatis的逆向工程差不多) 对应的依赖: ```xml com.baomidou mybatis-plus-generator 3.5.1 org.freemarker freemarker 2.3.31 ``` Generator.java ```java package com.yy.studymybatisplus; import com.baomidou.mybatisplus.generator.FastAutoGenerator; import com.baomidou.mybatisplus.generator.config.OutputFile; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; import java.util.Collections; public class Generator { public static void main(String[] args) { FastAutoGenerator.create("jdbc:mysql://yang1yu.site:3306/mybatis_plus?characterEncoding=utf-8&userSSL=false", "root", "yang1yu") .globalConfig(builder -> { builder.author("yang1yu") .fileOverride() // 覆盖已生成文件 .outputDir("E:\\CodeStudy\\Mybatis-Plus\\study-mybatis-plus\\generator"); // 指定输出目录 }) .packageConfig(builder -> { builder.parent("com.yy") // 设置父包名 .moduleName("mybatisplus") // 设置父包模块名 .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "E:\\CodeStudy\\Mybatis-Plus\\study-mybatis-plus\\generator")); }) .strategyConfig(builder -> { builder.addInclude("user"); // 设置需要生成的表名 // .addTablePrefix("t_", "c_"); // 设置过滤表前缀 }) .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker .execute(); } } ``` 会自动生成对应的controller,entity,mapper,service ![1661223458743](README.assets/1661223458743.png) ### 6. 多数据源 适用于多种场景,纯粹多库,读写分离,一主多从,混合模式等; ### 7. MybatisX插件 复杂SQL,多表联查等 https://baomidou.com/pages/ba5b24/#%E7%89%B9%E6%80%A7