Mybatis-plus之学习

825 阅读4分钟

Mybatis与JPA

JPA

JPA:java持久层API,可以理解为一种规范,Hibernate就是其具体一个实现。(目前比较常用的是SpringDataJpa,它是Spring提供的一套简化开发的框架,按照约定好的方法命名规则,编写dao层接口,就可以在不编写实现情况下执行数据库操作,还提供了除CRUD以外的功能,例如分页、排序、复杂查询等等,SpringDataJpa可以理解为对JPA的再次封装,底层仍旧是Hibernate)

JPA优势

  1. JPA移植性比较好(Hibernate方言)
  2. 提供了很多CRUD方法、开发效率高(不用编写sql语句)
  3. 对象化程度更高(面向对象开发思想)

Mybatis优势

  1. SQL语句可以自由控制,更灵活、性能较高。
  2. SQL与代码分离,易于阅读和维护。
  3. 提供XML标签,支持编写动态SQL语句。

Mybatis劣势

  1. 简单CRUD操作需要编写SQL语句(单表仍需要编写Mapper接口方法和xml的sql)
  2. XML中有大量sql需维护
  3. mybatis自身功能有限

Mybatis-plus

简介

Mybatis-plus简介:Mybatis增强工具,只做增强,不作改变,简化开发,提高效率。 官网地址:mybatis.plus/

  1. Crab:Mybatisplus3.0教学版。(MP核心程序员作品)
  2. Crab:WEB极速开发框架。(MP项目负责人作品) github项目地址:github.com/baomidou/my…

码云项目地址:gitee.com/baomidou/my…

架构

5da469820001a23519201080.jpg

Mybatis-plus特点:

  1. 无侵入(只做增强,不作改变)、损耗小(程序启动时,进行注入增强的功能)、强大的CRUD操作(通用Service、通用Mapper,通过少量配置可实现单表操作,类似Hibernate)、支持条件构造器,支持各类需求。
  2. 支持Lambda形式调用、提供了Lambda条件构造器,支持多种数据库(主流的Mysql、Oracle等)
  3. 支持主键生成策略、支持ActiveRecord模式(实体类只需要继承Model,然后通过实体类完成CRUD操作)。
  4. 支持全局自定义操作(支持全局通用方法注入)、支持关键词自动 转义(数据库关键词自动转义)
  5. 内置代码生成器(实体、Mapper接口、Mapper文件、Service、Controller)、内置分页插件(基于Mybatis的物理分页)、内置性能分析插件
  6. 内置全局拦截插件(提供了delete、update智能分析阻断,也可以自定义拦截规则,以防误操作)、内置sql注入剥离器(有效防止注入攻击)

SSM框架操作接口数据

5ce7f5570001104719201080.jpg

代码生成器

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

添加依赖

MyBatis-Plus 从 3.0.3 之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖:

  1. 添加 添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,用户可以选择自己熟悉的模板引擎,如果都不满足您的要求,可以采用自定义模板引擎 代码生成器 依赖
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.2</version>
</dependency>
  1. 添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,用户可以选择自己熟悉的模板引擎,如果都不满足您的要求,可以采用自定义模板引擎
  • Velocity(默认):
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>
  • Freemarker:
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.31</version>
</dependency>
  • Beetl:
<dependency>
    <groupId>com.ibeetl</groupId>
    <artifactId>beetl</artifactId>
    <version>3.3.2.RELEASE</version>
</dependency>

注意!如果您选择了非默认引擎,需要在 AutoGenerator 中 设置模板引擎。

AutoGenerator generator = new AutoGenerator();

// set freemarker engine
generator.setTemplateEngine(new FreemarkerTemplateEngine());

// set beetl engine
generator.setTemplateEngine(new BeetlTemplateEngine());

// set custom engine (reference class is your custom engine class)
generator.setTemplateEngine(new CustomTemplateEngine());

// other config
...

编写配置

MyBatis-Plus 的代码生成器提供了大量的自定义参数供用户选择,能够满足绝大部分人的使用需求。

  1. 配置 GlobalConfig
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
globalConfig.setAuthor("jobob");
globalConfig.setOpen(false);
  1. 配置 DataSourceConfig
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/ant?useUnicode=true&useSSL=false&characterEncoding=utf8");
dataSourceConfig.setDriverName("com.mysql.jdbc.Driver");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("password");

自定义模板引擎

请继承类 com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine

  1. 自定义代码模板
//指定自定义模板路径, 位置:/resources/templates/entity2.java.ftl(或者是.vm)
//注意不要带上.ftl(或者是.vm), 会根据使用的模板引擎自动识别
TemplateConfig templateConfig = new TemplateConfig()
    .setEntity("templates/entity2.java");

AutoGenerator mpg = new AutoGenerator();
//配置自定义模板
mpg.setTemplate(templateConfig);
  1. 自定义属性注入
InjectionConfig injectionConfig = new InjectionConfig() {
    //自定义属性注入:abc
    //在.ftl(或者是.vm)模板中,通过${cfg.abc}获取属性
    @Override
    public void initMap() {
        Map<String, Object> map = new HashMap<>();
        map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
        this.setMap(map);
    }
};
AutoGenerator mpg = new AutoGenerator();
//配置自定义属性注入
mpg.setCfg(injectionConfig);
entity2.java.ftl
自定义属性注入abc=${cfg.abc}

entity2.java.vm
自定义属性注入abc=$!{cfg.abc}
  1. 字段其他信息查询注入
new DataSourceConfig().setDbQuery(new MySqlQuery() {

    /**
     * 重写父类预留查询自定义字段<br>
     * 这里查询的 SQL 对应父类 tableFieldsSql 的查询字段,默认不能满足你的需求请重写它<br>
     * 模板中调用:  table.fields 获取所有字段信息,
     * 然后循环字段获取 field.customMap 从 MAP 中获取注入字段如下  NULL 或者 PRIVILEGES
     */
    @Override
    public String[] fieldCustom() {
        return new String[]{"NULL", "PRIVILEGES"};
    }
})

注解

@TableName 表名注解

属性类型必须指定默认值描述
valueString""表名
schemaString""schema
keepGlobalPrefixbooleanfalse是否保持使用全局的 tablePrefix 的值(如果设置了全局 tablePrefix 且自行设置了 value 的值)
resultMapString""xml 中 resultMap 的 id
autoResultMapbooleanfalse是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入)
excludePropertyString[]{}需要排除的属性名(@since 3.3.1)

关于autoResultMap的说明: mp会自动构建一个ResultMap并注入到mybatis里(一般用不上).下面讲两句: 因为mp底层是mybatis,所以一些mybatis的常识你要知道,mp只是帮你注入了常用crud到mybatis里 注入之前可以说是动态的(根据你entity的字段以及注解变化而变化),但是注入之后是静态的(等于你写在xml的东西) 而对于直接指定typeHandler,mybatis只支持你写在2个地方:

  1. 定义在resultMap里,只作用于select查询的返回结果封装
  2. 定义在insert和updatesql的#{property}里的property后面(例:#{property,typehandler=xxx.xxx.xxx}),只作用于设置值 而除了这两种直接指定typeHandler,mybatis有一个全局的扫描你自己的typeHandler包的配置,这是根据你的property的类型去找typeHandler并使用.

@TableId 主键注解

属性类型必须指定默认值描述
valueString""主键字段名
typeEnumIdType.NONE主键类型

IdType

描述
AUTO数据库ID自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert前自行set主键值
ASSIGN_ID分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)
ID_WORKER分布式全局唯一ID 长整型类型(please use ASSIGN_ID)
UUID32位UUID字符串(please use ASSIGN_UUID)
ID_WORKER_STR分布式全局唯一ID 字符串类型(please use ASSIGN_ID)

@TableField 字段注解(非主键)

属性类型必须指定默认值描述
valueString""数据库字段名
elString""映射为原生 #{ ... } 逻辑,相当于写在 xml 里的 #{ ... } 部分
existbooleantrue是否为数据库表字段
conditionString""字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s}
updateString""字段 update set 部分注入, 例如:update="%s+1":表示更新时会set version=version+1(该属性优先级高于 el 属性)
insertStrategyEnumNDEFAULT举例:NOT_NULL: insert into table_a(column) values (#{columnProperty})
updateStrategyEnumNDEFAULT举例:IGNORED: update table_a set column=#{columnProperty}
whereStrategyEnumNDEFAULT举例:NOT_EMPTY: where column=#{columnProperty}
fillEnumFieldFill.DEFAULT字段自动填充策略
selectbooleantrue是否进行 select 查询
keepGlobalFormatbooleanfalse是否保持使用全局的 format 进行处理
jdbcTypeJdbcTypeJdbcType.UNDEFINEDJDBC类型 (该默认值不代表会按照该值生效)
typeHandlerClass<? extends TypeHandler>UnknownTypeHandler.class类型处理器 (该默认值不代表会按照该值生效)
numericScaleString""指定小数点后保留的位数

关于jdbcTypetypeHandler以及numericScale的说明:

numericScale只生效于 update 的sql. jdbcType和typeHandler如果不配合@TableName#autoResultMap = true一起使用,也只生效于 update 的sql. 对于typeHandler如果你的字段类型和set进去的类型为equals关系,则只需要让你的typeHandler让Mybatis加载到即可,不需要使用注解

FieldStrategy

描述
IGNORED忽略判断
NOT_NULL非NULL判断
NOT_EMPTY非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断)
DEFAULT追随全局配置

FieldFill

描述
DEFAULT默认不处理
INSERT插入时填充字段
UPDATE更新时填充字段
INSERT_UPDATE插入和更新时填充字段

@Version 乐观锁注解、标记 @Verison 在字段上

@EnumValue 通枚举类注解(注解在枚举字段上)

@TableLogic 表字段逻辑处理注解(逻辑删除)

属性类型必须指定默认值描述
valueString""逻辑未删除值
delvalString""逻辑删除值

@KeySequence 序列主键策略

属性:value、resultMap

属性类型必须指定默认值描述
valueString""序列名
clazzClassLong.classid的类型, 可以指定String.class,这样返回的Sequence值是字符串"1"

@InterceptorIgnore 内置插件的一些过滤规则

CRUD 接口

Service CRUD 接口

  • 通用 Service CRUD 封装IService (opens new window)接口,进一步封装 CRUD 采用 get 查询单行 remove 删除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混淆,
  • 泛型 T 为任意实体对象
  • 建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承 Mybatis-Plus 提供的基类
  • 对象 Wrapper 为 条件构造器

save

// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);

参数说明

类型参数名描述
Tentity实体对象
CollectionentityList实体对象集合
intbatchSize插入批次数量

SaveOrUpdate

// TableId 注解存在更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);

参数说明

类型参数名描述
Tentity实体对象
WrapperupdateWrapper实体对象封装操作类 UpdateWrapper
CollectionentityList实体对象集合
intbatchSize插入批次数量

Remove

// 根据 entity 条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);

参数说明

类型参数名描述
WrapperqueryWrapper实体包装类 QueryWrapper
Serializableid主键ID
Map<String, Object>columnMap表字段 map 对象
Collection<? extends Serializable>idList主键ID列表

Update

// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);

参数说明

类型参数名描述
WrapperupdateWrapper实体对象封装操作类 UpdateWrapper
Tentity实体对象
CollectionentityList实体对象集合
intbatchSize更新批次数量

Get

// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

参数说明

类型参数名描述
Serializableid主键ID
WrapperqueryWrapper实体对象封装操作类 QueryWrapper
booleanthrowEx有多个 result 是否抛出异常
Tentity实体对象
Function<? super Object, V>mapper转换函数

List

// 查询所有
List<T> list();
// 查询列表
List<T> list(Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有列表
List<Map<String, Object>> listMaps();
// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询全部记录
List<Object> listObjs();
// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

参数说明

类型参数名描述
WrapperqueryWrapper实体对象封装操作类 QueryWrapper
Collection<? extends Serializable>idList主键ID列表
Map<?String, Object>columnMap表字段 map 对象
Function<? super Object, V>mapper转换函数

Page

// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

参数说明

类型参数名描述
IPagepage翻页对象
WrapperqueryWrapper实体对象封装操作类 QueryWrapper

Count

// 查询总记录数
int count();
// 根据 Wrapper 条件,查询总记录数
int count(Wrapper<T> queryWrapper);

参数说明

类型参数名描述
WrapperqueryWrapper实体对象封装操作类 QueryWrapper

Chain

query

// 链式查询 普通
QueryChainWrapper<T> query();
// 链式查询 lambda 式。注意:不支持 Kotlin
LambdaQueryChainWrapper<T> lambdaQuery(); 

// 示例:
query().eq("column", value).one();
lambdaQuery().eq(Entity::getId, value).list();

update

// 链式更改 普通
UpdateChainWrapper<T> update();
// 链式更改 lambda 式。注意:不支持 Kotlin 
LambdaUpdateChainWrapper<T> lambdaUpdate();

// 示例:
update().eq("column", value).remove();
lambdaUpdate().eq(Entity::getId, value).update(entity);

Mapper CRUD 接口

  • 通用 CRUD 封装BaseMapper (opens new window)接口,为 Mybatis-Plus 启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器
  • 泛型 T 为任意实体对象
  • 参数 Serializable 为任意类型主键 Mybatis-Plus 不推荐使用复合主键约定每一张表都有自己的唯一 id 主键
  • 对象 Wrapper 为 条件构造器

Insert

// 插入一条记录
int insert(T entity);

参数说明

类型参数名描述
Tentity实体对象

Delete

// 根据 entity 条件,删除记录
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 删除(根据ID 批量删除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 ID 删除
int deleteById(Serializable id);
// 根据 columnMap 条件,删除记录
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

参数说明

类型参数名描述
Wrapperwrapper实体对象封装操作类(可以为 null)
Collection<? extends Serializable>idList主键ID列表(不能为 null 以及 empty)
Serializableid主键ID
Map<String, Object>columnMap表字段 map 对象

Update

// 根据 whereWrapper 条件,更新记录
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
// 根据 ID 修改
int updateById(@Param(Constants.ENTITY) T entity);

参数说明

类型参数名描述
Tentity实体对象 (set 条件值,可为 null)
WrapperupdateWrapper实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
// 根据 ID 查询
T selectById(Serializable id);
// 根据 entity 条件,查询一条记录
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 查询(根据ID 批量查询)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根据 entity 条件,查询全部记录
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查询(根据 columnMap 条件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根据 Wrapper 条件,查询全部记录
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录。注意: 只返回第一个字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根据 entity 条件,查询全部记录(并翻页)
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录(并翻页)
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询总记录数
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

参数说明

类型参数名描述
Serializableid主键ID
WrapperqueryWrapper实体对象封装操作类(可以为 null)
Collection<? extends Serializable>idList主键ID列表(不能为 null 以及 empty)
Map<String, Object>columnMap表字段 map 对象
IPagepage分页查询条件(可以为 RowBounds.DEFAULT)

mapper 层 选装件

选装件位于 com.baomidou.mybatisplus.extension.injector.methods 包下 需要配合Sql 注入器使用

AlwaysUpdateSomeColumnById

int alwaysUpdateSomeColumnById(T entity);

insertBatchSomeColumn

int insertBatchSomeColumn(List<T> entityList);

deleteByIdWithFill

int deleteByIdWithFill(T entity);

条件构造器

  • 以下出现的第一个入参boolean condition表示该条件是否加入最后生成的sql中,例如:query.like(StringUtils.isNotBlank(name), Entity::getName, name) .eq(age!=null && age >= 0, Entity::getAge, age)
  • 以下代码块内的多个方法均为从上往下补全个别boolean类型的入参,默认为true
  • 以下出现的泛型Param均为Wrapper的子类实例(均具有AbstractWrapper的所有方法)
  • 以下方法在入参中出现的R为泛型,在普通wrapper中是String,在LambdaWrapper中是函数(例:Entity::getId,Entity为实体类,getId为字段id的getMethod)
  • 以下方法入参中的R column均表示数据库字段,当R具体类型为String时则为数据库字段名(字段名是数据库关键字的自己用转义符包裹!)!而不是实体类数据字段名!!!,另当R具体类型为SFunction时项目runtime不支持eclipse自家的编译器!!!
  • 以下举例均为使用普通wrapper,入参为Map和List的均以json形式表现!
  • 使用中如果入参的Map或者List为空,则不会加入最后生成的sql中!!!

警告: 不支持以及不赞成在 RPC 调用中把 Wrapper 进行传输

  • wrapper 很重
  • 传输 wrapper 可以类比为你的 controller 用 map 接收值(开发一时爽,维护火葬场)
  • 正确的 RPC 调用姿势是写一个 DTO 进行传输,被调用方再根据 DTO 执行相应的操作
  • 我们拒绝接受任何关于 RPC 传输 Wrapper 报错相关的 issue 甚至 pr

AbstractWrapper

QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类 用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件 注意: entity 生成的 where 条件与 使用各个 api 生成的 where 条件没有任何关联行为

allEq

allEq(Map<R, V> params)
allEq(Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, Map<R, V> params, boolean null2IsNull)
  • 全部eq(或个别isNull)

      参数说明:
      params : key为数据库字段名,value为字段值
      null2IsNull : 为true则在map的valuenull时调用 isNull 方法,为false时则忽略value
    
  1. 例1: allEq({id:1,name:"老王",age:null})--->id = 1 and name = '老王' and age is null
  2. 例2: allEq({id:1,name:"老王",age:null}, false)--->id = 1 and name = '老王'
allEq(BiPredicate<R, V> filter, Map<R, V> params)
allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)
allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) 
    参数说明:
    filter : 过滤函数,是否允许字段传入比对条件中
    params  null2IsNull : 同上
  1. 例1: allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null})--->name = '老王' and age is null
  2. 例2: allEq((k,v) -> k.indexOf("a") >= 0, {id:1,name:"老王",age:null}, false)--->name = '老王'

eq

含义为等于 =

eq(R column, Object val)
eq(boolean condition, R column, Object val)
  1. 例: eq("name", "老王")--->name = '老王'

ne

含义为不等于 !=

ne(R column, Object val)
ne(boolean condition, R column, Object val)
  1. 例: ne("name", "老王")--->name <> '老王'

gt

含义为大于 >

gt(R column, Object val)
gt(boolean condition, R column, Object val)
  1. 例: ge("age", 18)--->age > 18

ge

含义为大于等于 >=

ge(R column, Object val)
ge(boolean condition, R column, Object val)
  1. 例: ge("age", 18)--->age >= 18

lt

含义为小于 <

lt(R column, Object val)
lt(boolean condition, R column, Object val)
  1. 例: lt("age", 18)--->age < 18

le

含义为小于等于 <=

le(R column, Object val)
le(boolean condition, R column, Object val)
  1. 例: le("age", 18)--->age <= 18

between

含义为两者之间 between v1 and v2

between(R column, Object val1, Object val2)
between(boolean condition, R column, Object val1, Object val2)
  1. 例: between("age", 18, 30)--->age between 18 and 30

notBetween

含义为不在两者之间 not between v1 and v2

notBetween(R column, Object val1, Object val2)
notBetween(boolean condition, R column, Object val1, Object val2)
  1. 例: notBetween("age", 18, 30)--->age not between 18 and 30

like

含义为模糊匹配 like '%v1%'

like(R column, Object val)
like(boolean condition, R column, Object val)
  1. 例: like("name", "王")--->name like '%王%'

notLike

含义为模糊匹配取相反 not like '%v1%'

notLike(R column, Object val)
notLike(boolean condition, R column, Object val)
  1. 例: notLike("name", "王")--->name not like '%王%'

likeLeft

含义为左模糊匹配 like '%v1'

likeLeft(R column, Object val)
likeLeft(boolean condition, R column, Object val)
  1. 例: likeLeft("name", "王")--->name like '%王'

likeRight

含义为右模糊匹配 like 'v1%'

likeRight(R column, Object val)
likeRight(boolean condition, R column, Object val)
  1. 例: likeRight("name", "王")--->name like '王%'

isNull

含义为空 is null

isNull(R column)
isNull(boolean condition, R column)
  1. 例: isNotNull("name")--->name is null

isNotNull

含义为不为空 is not null

isNotNull(R column)
isNotNull(boolean condition, R column)
  1. 例: isNotNull("name")--->name is not null

in

含义为存在 in(v1,v2,v3....)

in(R column, Collection<?> value)
in(boolean condition, R column, Collection<?> value)
  1. 例: in("age",{1,2,3})--->age in (1,2,3)
in(R column, Object... values)
in(boolean condition, R column, Object... values)
  1. 例: in("age", 1, 2, 3)--->age in (1,2,3)

notIn

含义为不存在 not in(v1,v2,v3....)

notIn(R column, Collection<?> value)
notIn(boolean condition, R column, Collection<?> value)
  1. 例: notIn("age",{1,2,3})--->age not in (1,2,3)
notIn(R column, Object... values)
notIn(boolean condition, R column, Object... values)
  1. 例: notIn("age", 1, 2, 3)--->age not in (1,2,3)

inSql

含义为存在 in(v1,v2,v3....)

inSql(R column, String inValue)
inSql(boolean condition, R column, String inValue)
  1. 例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
  2. 例: inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)

notInSql

含义为不存在 not in(v1,v2,v3....)

notInSql(R column, String inValue)
notInSql(boolean condition, R column, String inValue)
  1. 例: notInSql("age", "1,2,3,4,5,6")--->age not in (1,2,3,4,5,6)
  2. 例: notInSql("id", "select id from table where id < 3")--->id not in (select id from table where id < 3)

groupBy

含义为分组 group by v1,v2,v3....

groupBy(R... columns)
groupBy(boolean condition, R... columns)
  1. 例: groupBy("id", "name")--->group by id,name

orderByAsc

含义为升序 order by v1 ASC,v2 ASC.....

orderByAsc(R... columns)
orderByAsc(boolean condition, R... columns)
  1. 例: orderByAsc("id", "name")--->order by id ASC,name ASC

orderByDesc

含义为降序 order by v1 DESC,v2 DESC.....

orderByDesc(R... columns)
orderByDesc(boolean condition, R... columns)
  1. 例: orderByDesc("id", "name")--->order by id DESC,name DESC

orderBy

含义为排序,升序 order by v1 ASC,v2 ASC.....

orderBy(boolean condition, boolean isAsc, R... columns)
  1. 例: orderBy(true, true, "id", "name")--->order by id ASC,name ASC

having

含义为 having(sql语句)

having(String sqlHaving, Object... params)
having(boolean condition, String sqlHaving, Object... params)
  1. 例: having("sum(age) > 10")--->having sum(age) > 10
  2. 例: having("sum(age) > {0}", 11)--->having sum(age) > 11

func

含义为 func 方法(主要方便在出现if...else下调用不同方法能不断链)

func(Consumer<Children> consumer)
func(boolean condition, Consumer<Children> consumer)
  1. 例: func(i -> if(true) {i.eq("id", 1)} else {i.ne("id", 1)})

or

含义为或者 or()

注意事项:主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接)

or()
or(boolean condition)
  1. 例: eq("id",1).or().eq("name","老王")--->id = 1 or name = '老王'
or(Consumer<Param> consumer)
or(boolean condition, Consumer<Param> consumer)
  1. 例: or(i -> i.eq("name", "李白").ne("status", "活着"))--->or (name = '李白' and status <> '活着')

and

含义为并且 and()

and(Consumer<Param> consumer)
and(boolean condition, Consumer<Param> consumer)
  1. 例: and(i -> i.eq("name", "李白").ne("status", "活着"))--->and (name = '李白' and status <> '活着')

nested

含义为 正常嵌套 不带 AND 或者 OR

nested(Consumer<Param> consumer)
nested(boolean condition, Consumer<Param> consumer)
  1. 例: nested(i -> i.eq("name", "李白").ne("status", "活着"))--->(name = '李白' and status <> '活着')

apply

含义为 拼接 sql

apply(String applySql, Object... params)
apply(boolean condition, String applySql, Object... params)
  1. 例: apply("id = 1")--->id = 1
  2. 例: apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
  3. 例: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'") 注意事项: 该方法可用于数据库函数 动态入参的params对应前面applySql内部的{index}部分.这样是不会有sql注入风险的,反之会有!

last

含义为 无视优化规则直接拼接到 sql 的最后

last(String lastSql)
last(boolean condition, String lastSql)
  1. 例: last("limit 1") 注意事项: 只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用

exists

含义为 拼接 EXISTS ( sql语句 )

exists(String existsSql)
exists(boolean condition, String existsSql)
  1. 例: exists("select id from table where age = 1")--->exists (select id from table where age = 1)

notExists

含义为 拼接 NOT EXISTS ( sql语句 )

notExists(String notExistsSql)
notExists(boolean condition, String notExistsSql)
  1. 例: notExists("select id from table where age = 1")--->not exists (select id from table where age = 1)

QueryWrapper

说明: 继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件 及 LambdaQueryWrapper, 可以通过 new QueryWrapper().lambda() 方法获取

select

含义为 设置查询字段

select(String... sqlSelect)
select(Predicate<TableFieldInfo> predicate)
select(Class<T> entityClass, Predicate<TableFieldInfo> predicate)
  1. 例: select("id", "name", "age")
  2. 例: select(i -> i.getProperty().startsWith("test")) 说明: 以上方法分为两类. 第二类方法为:过滤查询字段(主键除外),入参不包含 class 的调用前需要wrapper内的entity属性有值! 这两类方法重复调用以最后一次为准

UpdateWrapper

说明: 继承自 AbstractWrapper ,自身的内部属性 entity 也用于生成 where 条件 及 LambdaUpdateWrapper, 可以通过 new UpdateWrapper().lambda() 方法获取!

set

含义为 SQL SET 字段

set(String column, Object val)
set(boolean condition, String column, Object val)
  1. 例: set("name", "老李头")
  2. 例: set("name", "")--->数据库字段值变为空字符串
  3. 例: set("name", null)--->数据库字段值变为null

setSql

含义为 设置 SET 部分 SQL

setSql(String sql)
  1. 例: setSql("name = '老李头'")

lambda

  • 获取 LambdaWrapper
  • 在QueryWrapper中是获取LambdaQueryWrapper
  • 在UpdateWrapper中是获取LambdaUpdateWrapper

使用 Wrapper 自定义SQL

注意事项: 需要mybatis-plus版本 >= 3.0.7 param 参数名要么叫ew,要么加上注解@Param(Constants.WRAPPER) 使用${ew.customSqlSegment} 不支持 Wrapper 内的entity生成where语句

用注解

@Select("select * from mysql_data ${ew.customSqlSegment}")
List<MysqlData> getAll(@Param(Constants.WRAPPER) Wrapper wrapper);

用XML

List<MysqlData> getAll(Wrapper ew);
<select id="getAll" resultType="MysqlData">
	SELECT * FROM mysql_data ${ew.customSqlSegment}
</select>

链式调用 lambda 式

// 区分:
// 链式调用 普通
UpdateChainWrapper<T> update();
// 链式调用 lambda 式。注意:不支持 Kotlin 
LambdaUpdateChainWrapper<T> lambdaUpdate();

// 等价示例:
query().eq("id", value).one();
lambdaQuery().eq(Entity::getId, value).one();

// 等价示例:
update().eq("id", value).remove();
lambdaUpdate().eq(Entity::getId, value).remove();