MyBatis-Plus MyBatis-Plus
首页
  • 快速入门
  • 核心功能
  • 扩展
  • 插件
  • 使用配置
  • 代码生成器配置新
  • 代码生成器配置旧
生态
问答
💖支持
  • 数据处理模块
  • 单体开发平台
  • 微服务开发平台
  • 插件式一体化开发平台
更新日志 (opens new window)
GitHub (opens new window)
首页
  • 快速入门
  • 核心功能
  • 扩展
  • 插件
  • 使用配置
  • 代码生成器配置新
  • 代码生成器配置旧
生态
问答
💖支持
  • 数据处理模块
  • 单体开发平台
  • 微服务开发平台
  • 插件式一体化开发平台
更新日志 (opens new window)
GitHub (opens new window)
  • 快速入门

    • 简介
    • 快速开始
    • 安装
    • 配置
    • 注解
    • 快速测试
  • 核心功能

    • 代码生成器(新)
    • 代码生成器(旧)
    • CRUD 接口
    • 条件构造器
      • AbstractWrapper
        • allEq
        • eq
        • ne
        • gt
        • ge
        • lt
        • le
        • between
        • notBetween
        • like
        • notLike
        • likeLeft
        • likeRight
        • notLikeLeft
        • notLikeRight
        • isNull
        • isNotNull
        • in
        • notIn
        • inSql
        • notInSql
        • groupBy
        • orderByAsc
        • orderByDesc
        • orderBy
        • having
        • func
        • or
        • and
        • nested
        • apply
        • last
        • exists
        • notExists
      • QueryWrapper
        • select
      • UpdateWrapper
        • set
        • setSql
        • lambda
      • 使用 Wrapper 自定义SQL
        • kotlin持久化对象定义最佳实践
        • 用注解
        • 用XML
        • kotlin使用wrapper
        • 链式调用 lambda 式
    • 主键策略
    • 自定义ID生成器
  • 扩展

    • 逻辑删除
    • 通用枚举
    • 字段类型处理器
    • 自动填充功能
    • SQL注入器
    • 执行SQL分析打印
    • 数据安全保护
    • 多数据源
    • MybatisX快速开发插件
    • 企业高级特性
    • 脚本自动维护
  • 插件

    • 插件主体
    • 分页插件
    • 乐观锁插件
    • 多租户插件
    • 防全表更新与删除插件
    • 动态表名插件
目录

条件构造器

说明:

  • 以下出现的第一个入参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的getter Method)
  • 以下方法入参中的R column均表示数据库字段,当R具体类型为String时则为数据库字段名(字段名是数据库关键字的自己用转义符包裹!)!而不是实体类数据字段名!!!,另当R具体类型为SFunction时项目runtime不支持eclipse自家的编译器!!!
  • 以下举例均为使用普通wrapper,入参为Map和List的均以json形式表现!
  • 使用中如果入参的Map或者List为空,则不会加入最后生成的sql中!!!
  • 有任何疑问就点开源码看,看不懂函数的点击我学习新知识 (opens new window)

警告:

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

  1. wrapper 很重
  2. 传输 wrapper 可以类比为你的 controller 用 map 接收值(开发一时爽,维护火葬场)
  3. 正确的 RPC 调用姿势是写一个 DTO 进行传输,被调用方再根据 DTO 执行相应的操作
  4. 我们拒绝接受任何关于 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)
1
2
3
  • 全部eq(或个别isNull)

    个别参数说明:

    params : key为数据库字段名,value为字段值
    null2IsNull : 为true则在map的value为null时调用 isNull 方法,为false时则忽略value为null的

  • 例1: allEq({id:1,name:"老王",age:null})--->id = 1 and name = '老王' and age is null
  • 例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) 
1
2
3

个别参数说明:

filter : 过滤函数,是否允许字段传入比对条件中
params 与 null2IsNull : 同上

  • 例1: allEq((k,v) -> k.contains("a"), {id:1,name:"老王",age:null})--->name = '老王' and age is null
  • 例2: allEq((k,v) -> k.contains("a"), {id:1,name:"老王",age:null}, false)--->name = '老王'

# eq


 

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

# ne


 

ne(R column, Object val)
ne(boolean condition, R column, Object val)
1
2
  • 不等于 <>
  • 例: ne("name", "老王")--->name <> '老王'

# gt


 

gt(R column, Object val)
gt(boolean condition, R column, Object val)
1
2
  • 大于 >
  • 例: gt("age", 18)--->age > 18

# ge


 

ge(R column, Object val)
ge(boolean condition, R column, Object val)
1
2
  • 大于等于 >=
  • 例: ge("age", 18)--->age >= 18

# lt


 

lt(R column, Object val)
lt(boolean condition, R column, Object val)
1
2
  • 小于 <
  • 例: lt("age", 18)--->age < 18

# le


 

le(R column, Object val)
le(boolean condition, R column, Object val)
1
2
  • 小于等于 <=
  • 例: le("age", 18)--->age <= 18

# between


 

between(R column, Object val1, Object val2)
between(boolean condition, R column, Object val1, Object val2)
1
2
  • BETWEEN 值1 AND 值2
  • 例: between("age", 18, 30)--->age between 18 and 30

# notBetween


 

notBetween(R column, Object val1, Object val2)
notBetween(boolean condition, R column, Object val1, Object val2)
1
2
  • NOT BETWEEN 值1 AND 值2
  • 例: notBetween("age", 18, 30)--->age not between 18 and 30

# like


 

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

# notLike


 

notLike(R column, Object val)
notLike(boolean condition, R column, Object val)
1
2
  • NOT LIKE '%值%'
  • 例: notLike("name", "王")--->name not like '%王%'

# likeLeft


 

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

# likeRight


 

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

# notLikeLeft


 

notLikeLeft(R column, Object val)
notLikeLeft(boolean condition, R column, Object val)
1
2
  • NOT LIKE '%值'
  • 例: notLikeLeft("name", "王")--->name not like '%王'

# notLikeRight


 

notLikeRight(R column, Object val)
notLikeRight(boolean condition, R column, Object val)
1
2
  • NOT LIKE '值%'
  • 例: notLikeRight("name", "王")--->name not like '王%'

# isNull


 

isNull(R column)
isNull(boolean condition, R column)
1
2
  • 字段 IS NULL
  • 例: isNull("name")--->name is null

# isNotNull


 

isNotNull(R column)
isNotNull(boolean condition, R column)
1
2
  • 字段 IS NOT NULL
  • 例: isNotNull("name")--->name is not null

# in


 

in(R column, Collection<?> value)
in(boolean condition, R column, Collection<?> value)
1
2
  • 字段 IN (value.get(0), value.get(1), ...)
  • 例: in("age",{1,2,3})--->age in (1,2,3)

 

in(R column, Object... values)
in(boolean condition, R column, Object... values)
1
2
  • 字段 IN (v0, v1, ...)
  • 例: in("age", 1, 2, 3)--->age in (1,2,3)

# notIn


 

notIn(R column, Collection<?> value)
notIn(boolean condition, R column, Collection<?> value)
1
2
  • 字段 NOT IN (value.get(0), value.get(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
2
  • 字段 NOT IN (v0, v1, ...)
  • 例: notIn("age", 1, 2, 3)--->age not in (1,2,3)

# inSql


 

inSql(R column, String inValue)
inSql(boolean condition, R column, String inValue)
1
2
  • 字段 IN ( sql语句 )
  • 例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)
  • 例: inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)

# notInSql


 

notInSql(R column, String inValue)
notInSql(boolean condition, R column, String inValue)
1
2
  • 字段 NOT IN ( sql语句 )
  • 例: notInSql("age", "1,2,3,4,5,6")--->age not in (1,2,3,4,5,6)
  • 例: notInSql("id", "select id from table where id < 3")--->id not in (select id from table where id < 3)

# groupBy


 

groupBy(R... columns)
groupBy(boolean condition, R... columns)
1
2
  • 分组:GROUP BY 字段, ...
  • 例: groupBy("id", "name")--->group by id,name

# orderByAsc


 

orderByAsc(R... columns)
orderByAsc(boolean condition, R... columns)
1
2
  • 排序:ORDER BY 字段, ... ASC
  • 例: orderByAsc("id", "name")--->order by id ASC,name ASC

# orderByDesc


 

orderByDesc(R... columns)
orderByDesc(boolean condition, R... columns)
1
2
  • 排序:ORDER BY 字段, ... DESC
  • 例: orderByDesc("id", "name")--->order by id DESC,name DESC

# orderBy

 

orderBy(boolean condition, boolean isAsc, R... columns)
1
  • 排序:ORDER BY 字段, ...
  • 例: orderBy(true, true, "id", "name")--->order by id ASC,name ASC

# having


 

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

# func


 

func(Consumer<Children> consumer)
func(boolean condition, Consumer<Children> consumer)
1
2
  • func 方法(主要方便在出现if...else下调用不同方法能不断链)
  • 例: func(i -> if(true) {i.eq("id", 1)} else {i.ne("id", 1)})

# or


 

or()
or(boolean condition)
1
2
  • 拼接 OR

    注意事项:

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

  • 例: eq("id",1).or().eq("name","老王")--->id = 1 or name = '老王'

 

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

# and


 

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

# nested


 

nested(Consumer<Param> consumer)
nested(boolean condition, Consumer<Param> consumer)
1
2
  • 正常嵌套 不带 AND 或者 OR
  • 例: nested(i -> i.eq("name", "李白").ne("status", "活着"))--->(name = '李白' and status <> '活着')

# apply


 

apply(String applySql, Object... params)
apply(boolean condition, String applySql, Object... params)
1
2
  • 拼接 sql

    注意事项:

    该方法可用于数据库函数 动态入参的params对应前面applySql内部的{index}部分.这样是不会有sql注入风险的,反之会有!

  • 例: apply("id = 1")--->id = 1
  • 例: apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")
  • 例: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")--->date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")

# last


 

last(String lastSql)
last(boolean condition, String lastSql)
1
2
  • 无视优化规则直接拼接到 sql 的最后

    注意事项:

    只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用

  • 例: last("limit 1")

# exists


 

exists(String existsSql)
exists(boolean condition, String existsSql)
1
2
  • 拼接 EXISTS ( sql语句 )
  • 例: exists("select id from table where age = 1")--->exists (select id from table where age = 1)

# notExists


 

notExists(String notExistsSql)
notExists(boolean condition, String notExistsSql)
1
2
  • 拼接 NOT EXISTS ( sql语句 )
  • 例: 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
2
3
  • 设置查询字段

    说明:

    以上方法分为两类.
    第二类方法为:过滤查询字段(主键除外),入参不包含 class 的调用前需要wrapper内的entity属性有值! 这两类方法重复调用以最后一次为准

  • 例: select("id", "name", "age")
  • 例: select(i -> i.getProperty().startsWith("test"))

# UpdateWrapper

说明:

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

# set


 

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

# setSql

setSql(String sql)
1
  • 设置 SET 部分 SQL
  • 例: 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语句

# kotlin持久化对象定义最佳实践

由于kotlin相比于java多了数据对象(data class),在未说明情况下可能会混用。建议按照以下形式定义持久化对象

@TableName("sys_user")
class User {
		@TableId(type = IdType.AUTO)
    var id: Int? = null

    @TableField("username")
    var name: String? = null

    var roleId: Int? = null
}
1
2
3
4
5
6
7
8
9
10

注意:这里的TableId及TableField并非必要,只是为了展示Mybatis-Plus中的annotation使用

这里所有成员都需要定义为可空类型(?),并赋予null的初始值,方便我们在以下场景中使用(类似java中的updateSelective)

val wrapper = KtUpdateWrapper(User::class.java).eq(User::id, 2)
val newRecord = User()
newRecord.name = "newName"
userMapper!!.update(newRecord, wrapper)
1
2
3
4

不建议使用data class及全参数构造方法,这样我们会写很多不必要的null来构造一个空对象

# 用注解

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

# 用XML

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

# kotlin使用wrapper

kotlin 可以使用 QueryWrapper 和 UpdateWrapper 但无法使用 LambdaQueryWrapper 和 LambdaUpdateWrapper
如果想使用 lambda 方式的 wrapper 请使用 KtQueryWrapper 和 KtUpdateWrapper

请参考实例 (opens new window)

val queryWrapper = KtQueryWrapper(User()).eq(User::name, "sss").eq(User::roleId, "sss2")
userMapper!!.selectList(queryWrapper)

val updateConditionWrapper = KtUpdateWrapper(User()).eq(User::name, "sss").eq(User::roleId, "sss2")
val updateRecord = User()
updateRecord.name = "newName"
userMapper!!.update(updateRecord, updateConditionWrapper)

val updateRecord = User()
updateRecord.id = 2
updateRecord.name = "haha"
userMapper.updateById(updateRecord)
1
2
3
4
5
6
7
8
9
10
11
12

# 链式调用 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();
1
2
3
4
5
6
7
8
9
10
11
12
13
帮助我们改善此页面! (opens new window)
上次更新: 2022/12/29, 05:38:23
CRUD 接口
主键策略

← CRUD 接口 主键策略→

Theme by Vdoing | Copyright © 2016-2023 Team Baomidou | Sponsored by JetBrains | 渝ICP备2021000141号-1

友情链接:AiZuDa | D.Yang | NanCheung | apidocsBlog

  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×