一、简介
MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。
二、特点
-
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
-
损耗小:启动即会自动注入基本 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 等多种数据库
-
内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
-
内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
三、安装
-
JDK 8+
-
Maven or Gradle
com.baomidou mybatis-plus-boot-starter 3.5.1
引入
MyBatis-Plus
之后请不要再次引入MyBatis
以及MyBatis-Spring
,以避免因版本差异导致的问题。
四、代码生成器
AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
1、安装
com.baomidou mybatis-plus-generator 3.5.1 org.freemarker freemarker
当前包未传递依赖 MP 包,需要自己引入!
适用版本:mybatis-plus-generator 3.5.1 及其以上版本,对历史版本不兼容!3.5.1 以下的请参考 代码生成器旧
2、快速生成
3、代码修改
package cn.kgc.mybatisplus;import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.generator.FastAutoGenerator;import com.baomidou.mybatisplus.generator.config.OutputFile;import com.baomidou.mybatisplus.generator.config.rules.DateType;import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;import com.zaxxer.hikari.util.SuspendResumeLock;import java.util.Collections;public class MyBatisPlusGeneratorV2{ private static final String URL = "jdbc:mysql://localhost:3306/book"; private static final String USERNAME = "root"; private static final String PASSWORD = "root"; private static final String AUTHOR = "cuiyi
cuiyi@zbitedu.cn"; private static final String OUT_PUT_DIR = System.getProperty("user.dir") + "/src/main/java"; private static final DateType DATE_TYPE = DateType.ONLY_DATE; // 使用java.util.date private static final String PARENT_PACKAGE = "cn.kgc"; private static final String MODULE_NAME = "mybatisplus"; private static final String MAPPER_LOCATION = System.getProperty("user.dir") + "/src/main/resources/mappers"; private static final String TABLE_PREFIX = "t_"; private static final IdType IDTYPE = IdType.ASSIGN_ID; public static void main(String[] args) { FastAutoGenerator .create(URL,USERNAME,PASSWORD) .globalConfig(builder -> { builder.author(AUTHOR) // 设置作者 //.enableSwagger() // 开启 swagger 模式 .fileOverride() // 覆盖已生成文件 .outputDir(OUT_PUT_DIR)// 指定输出目录 .disableOpenDir() .dateType(DATE_TYPE); }) .packageConfig(builder -> { builder.parent(PARENT_PACKAGE) // 设置父包名 .moduleName(MODULE_NAME) // 设置父包模块名 .pathInfo(Collections.singletonMap(OutputFile.mapperXml, MAPPER_LOCATION )); // 设置mapperXml生成路径 }) .strategyConfig(builder -> { builder .addTablePrefix(TABLE_PREFIX) .entityBuilder() .enableLombok() .idType(IDTYPE) .controllerBuilder() .enableRestStyle() .serviceBuilder() .convertServiceFileName(entityName -> entityName+"Service") ; // 设置过滤表前缀 }) .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板 .execute(); }}
五、CURD接口
1、Service层接口
说明:
-
通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用
get 查询单行
remove 删除
list 查询集合
page 分页
前缀命名方式区分Mapper
层避免混淆, -
泛型
T
为任意实体对象 -
建议如果存在自定义通用 Service 方法的可能,请创建自己的
IBaseService
继承Mybatis-Plus
提供的基类 -
对象
Wrapper
为 条件构造器,用于构造where条件
1-1 Save
// 插入一条记录(选择字段,策略插入)boolean save(T entity);// 插入(批量)boolean saveBatch(Collection entityList);// 插入(批量)boolean saveBatch(Collection entityList, int batchSize);
1-2 SaveOrUpdate
// TableId 注解的字段存在更新记录,否插入一条记录// 没有id或者有id但是数据库没有数据:save boolean saveOrUpdate(T entity);// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法boolean saveOrUpdate(T entity, Wrapper updateWrapper);// 批量修改插入boolean saveOrUpdateBatch(Collection entityList);// 批量修改插入boolean saveOrUpdateBatch(Collection entityList, int batchSize);
1-3 Remove
// 根据 entity 条件,删除记录boolean remove(Wrapper queryWrapper);// 根据 ID 删除boolean removeById(Serializable id);// 根据 columnMap 条件,删除记录boolean removeByMap(Map columnMap);// 删除(根据ID 批量删除)boolean removeByIds(Collection extends Serializable> idList);
1-4 Update
// 根据 UpdateWrapper 条件,更新记录 需要设置sqlsetboolean update(Wrapper updateWrapper);// 根据 whereWrapper 条件,更新记录boolean update(T updateEntity, Wrapper whereWrapper);// 根据 ID 选择修改 动态SQLboolean updateById(T entity);// 根据ID 批量更新boolean updateBatchById(Collection entityList);// 根据ID 批量更新boolean updateBatchById(Collection entityList, int batchSize);
1-5 Get
// 根据 ID 查询T getById(Serializable id);// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")T getOne(Wrapper queryWrapper);// 根据 Wrapper,查询一条记录T getOne(Wrapper queryWrapper, boolean throwEx);// 根据 Wrapper,查询一条记录Map getMap(Wrapper queryWrapper);// 根据 Wrapper,查询一条记录 V getObj(Wrapper queryWrapper, Function super Object, V> mapper);
1-6 List
// 查询所有List list();// 查询列表List list(Wrapper queryWrapper);// 查询(根据ID 批量查询)Collection listByIds(Collection extends Serializable> idList);// 查询(根据 columnMap 条件)Collection listByMap(Map columnMap);// 查询所有列表List
1-7 Page
先配置分页插件
API方法
// 无条件分页查询IPage page(IPage page);// 条件分页查询IPage page(IPage page, Wrapper queryWrapper);// 无条件分页查询IPage> pageMaps(IPage page);// 条件分页查询IPage> pageMaps(IPage page, Wrapper queryWrapper);
1-8 Count
// 查询总记录数int count();// 根据 Wrapper 条件,查询总记录数int count(Wrapper queryWrapper);
2、Mapper层接口
-
通用 CRUD 封装BaseMapper接口,为
Mybatis-Plus
启动时自动解析实体表关系映射转换为Mybatis
内部对象注入容器 -
泛型
T
为任意实体对象 -
参数
Serializable
为任意类型主键Mybatis-Plus
不推荐使用复合主键约定每一张表都有自己的唯一id
主键 -
对象
Wrapper
为 条件构造器 -
Service实现类中内置了
-
baseMapper 属性
-
getBeseMapper 方法
-
2-1 Insert
// 插入一条记录int insert(T entity);
2-2 Delete
int delete(@Param(Constants.WRAPPER) Wrapper wrapper);// 删除(根据ID 批量删除)int deleteBatchIds(@Param(Constants.COLLECTION) Collection extends Serializable> idList);// 根据 ID 删除int deleteById(Serializable id);// 根据 columnMap 条件,删除记录int deleteByMap(@Param(Constants.COLUMN_MAP) Map columnMap);
2-3 Update
// 根据 whereWrapper 条件,更新记录int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper whereWrapper);// 根据 ID 修改int updateById(@Param(Constants.ENTITY) T entity);
2-4 Select
// 根据 ID 查询T selectById(Serializable id);// 根据 entity 条件,查询一条记录T selectOne(@Param(Constants.WRAPPER) Wrapper queryWrapper);// 查询(根据ID 批量查询)List selectBatchIds(@Param(Constants.COLLECTION) Collection extends Serializable> idList);// 根据 entity 条件,查询全部记录List selectList(@Param(Constants.WRAPPER) Wrapper queryWrapper);// 查询(根据 columnMap 条件)List selectByMap(@Param(Constants.COLUMN_MAP) Map columnMap);// 根据 Wrapper 条件,查询全部记录List> selectMaps(@Param(Constants.WRAPPER) Wrapper queryWrapper);// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值List selectObjs(@Param(Constants.WRAPPER) Wrapper queryWrapper);// 根据 entity 条件,查询全部记录(并翻页)IPage selectPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper);// 根据 Wrapper 条件,查询全部记录(并翻页)IPage> selectMapsPage(IPage page, @Param(Constants.WRAPPER) Wrapper queryWrapper);// 根据 Wrapper 条件,查询总记录数Integer selectCount(@Param(Constants.WRAPPER) Wrapper queryWrapper);
2-5 自定义Mapper方法
3、ActiveRecord 模式
说明:
实体类只需继承 Model 类即可进行强大的 CRUD 操作
需要项目中已注入对应实体的BaseMapper
class User extends Model{ // fields...}
User user = new User();user.insert();user.selectAll();user.updateById();user.deleteById();// ...
六、条件构造器
1、AbstractWrapper
1-1 说明
QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类 用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件 注意: entity 生成的 where 条件与 使用各个 api 生成的 where 条件没有任何关联行为
1-2 常用方法
allEq、eq、ne、gt、ge、lt、le、between、notBetween、like、notLike、likeLeft、likeRight、isNull、isNotNull、in、notIn、inSql、notInSql、groupBy、orderByAsc、orderByDesc、orderBy、having、func、or、and、nested、apply、last、exists、notExists
2、实现类
QueryWrapper :查询用Wrapper / LambdaQueryWrapper: Lambda方式构造Wrapper
UpdateWrapper:修改用Wrapper / LambdaUpdateWrapper:Lambda方式构造Wrapper
3、Wrapper创建方式
以Query为例
3-1 方式1
QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("id",2);wrapper.like("url","https");
QueryWrapper wrapper = Wrappers.query();wrapper.eq("id",2);wrapper.like("url","https");
破环三层结构, 不要使用
3-2 方式2
Advs advs = new Advs();QueryWrapper wrapper = new QueryWrapper<>(advs);
Advs advs = new Advs();QueryWrapper wrapper = Wrappers.query(advs);
使用对象构建查询条件。
3-3 方式3
使用LambdaQueryWrapper
LambdaQueryWrapper wrapper = Wrappers .lambdaQuery(Advs.class) .eq(Advs::getUrl,"someUrl");
Advs advs = new Advs();LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(advs) .eq(Advs::getUrl,advs.getUrl());
LambdaQueryWrapper wrapper =new LambdaQueryWrapper<>();wrapper.eq(Advs::getUrl,"someUrl");
Wrapper中所有的条件构建方法都可以多传入第一个参数,一个boolean类型参数,当值为true时,才在SQL中拼接该条件
七、分页
@Configurationpublic class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor( new PaginationInnerInterceptor(DbType.MYSQL) ); return interceptor; }}
方式1
@RequestMapping("/page")public R page(Page p){ IPage page = productService.page(p); return R.success(page);}
方式2
@RequestMapping("/page")public R page( @RequestParam(value = "page",defaultValue = "1", required = false)Integer curPage, @RequestParam(value = "rows",defaultValue = "4", required = false)Integer rows){// Page p = new Page(curPage,rows); Page p = Page.of(curPage,rows); IPage page = productService.page(p); return R.success(page);}
方式3
@Repositorypublic interface ProductMapper extends BaseMapper { // 如果需要自定义查询+分页, // 只需要将Page对象作为Mapper接口方法的第一个参数传入即可 Page selectFuzzy(Page p,@Param("pro") Product product);}
注意: 其他普通参数,就需要添加@Param注解!
如果认为 Page 对象不够,或者不满足 项目需求, 可以自己实现IPage接口/继承Page类, 重构Page对象
八、主键生成策略
@Getterpublic enum IdType { AUTO(0), NONE(1), INPUT(2), ASSIGN_ID(3), ASSIGN_UUID(4);}
九、扩展
十、企业高级特性
十一、插件
1、总览
来源地址:https://blog.csdn.net/shjsnsj/article/details/129762662