MyBatis-Plus 条件构造器

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: MyBatis-Plus 条件构造器

 说明:

    • 以下出现的第一个入参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时则为数据库字段名(字段名是数据库关键字的自己用转义符包裹!)而不是实体类数据字段名!!!
    • 以下举例均为使用普通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)

      image.gif

        • 全部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)

        image.gif

        个别参数说明:

        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)

          image.gif

            • 等于 =
            • 例: eq("name", "老王")--->name = '老王'

            #ne

            ne(R column, Object val)
            ne(boolean condition, R column, Object val)

            image.gif

              • 不等于 <>
              • 例: ne("name", "老王")--->name <> '老王'

              #gt

              gt(R column, Object val)
              gt(boolean condition, R column, Object val)

              image.gif

                • 大于 >
                • 例: gt("age", 18)--->age > 18

                #ge

                ge(R column, Object val)
                ge(boolean condition, R column, Object val)

                image.gif

                  • 大于等于 >=
                  • 例: ge("age", 18)--->age >= 18

                  #lt

                  lt(R column, Object val)
                  lt(boolean condition, R column, Object val)

                  image.gif

                    • 小于 <
                    • 例: lt("age", 18)--->age < 18

                    #le

                    le(R column, Object val)
                    le(boolean condition, R column, Object val)

                    image.gif

                      • 小于等于 <=
                      • 例: le("age", 18)--->age <= 18

                      #between

                      between(R column, Object val1, Object val2)
                      between(boolean condition, R column, Object val1, Object val2)

                      image.gif

                        • 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)

                        image.gif

                          • 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)

                          image.gif

                            • LIKE '%值%'
                            • 例: like("name", "王")--->name like '%王%'

                            #notLike

                            notLike(R column, Object val)
                            notLike(boolean condition, R column, Object val)

                            image.gif

                              • NOT LIKE '%值%'
                              • 例: notLike("name", "王")--->name not like '%王%'

                              #likeLeft

                              likeLeft(R column, Object val)
                              likeLeft(boolean condition, R column, Object val)

                              image.gif

                                • LIKE '%值'
                                • 例: likeLeft("name", "王")--->name like '%王'

                                #likeRight

                                likeRight(R column, Object val)
                                likeRight(boolean condition, R column, Object val)

                                image.gif

                                  • LIKE '值%'
                                  • 例: likeRight("name", "王")--->name like '王%'

                                  #notLikeLeft

                                  notLikeLeft(R column, Object val)
                                  notLikeLeft(boolean condition, R column, Object val)

                                  image.gif

                                    • NOT LIKE '%值'
                                    • 例: notLikeLeft("name", "王")--->name not like '%王'

                                    #notLikeRight

                                    notLikeRight(R column, Object val)
                                    notLikeRight(boolean condition, R column, Object val)

                                    image.gif

                                      • NOT LIKE '值%'
                                      • 例: notLikeRight("name", "王")--->name not like '王%'

                                      #isNull

                                      isNull(R column)
                                      isNull(boolean condition, R column)

                                      image.gif

                                        • 字段 IS NULL
                                        • 例: isNull("name")--->name is null

                                        #isNotNull

                                        isNotNull(R column)
                                        isNotNull(boolean condition, R column)

                                        image.gif

                                          • 字段 IS NOT NULL
                                          • 例: isNotNull("name")--->name is not null

                                          #in

                                          in(R column, Collection<?> value)
                                          in(boolean condition, R column, Collection<?> value)

                                          image.gif

                                            • 字段 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)

                                            image.gif

                                              • 字段 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)

                                              image.gif

                                                • 字段 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)

                                                image.gif

                                                  • 字段 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)

                                                  image.gif

                                                    • 字段 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)

                                                    image.gif

                                                      • 字段 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)

                                                      image.gif

                                                        • 分组:GROUP BY 字段, ...
                                                        • 例: groupBy("id", "name")--->group by id,name

                                                        #orderByAsc

                                                        orderByAsc(R... columns)
                                                        orderByAsc(boolean condition, R... columns)

                                                        image.gif

                                                          • 排序:ORDER BY 字段, ... ASC
                                                          • 例: orderByAsc("id", "name")--->order by id ASC,name ASC

                                                          #orderByDesc

                                                          orderByDesc(R... columns)
                                                          orderByDesc(boolean condition, R... columns)

                                                          image.gif

                                                            • 排序:ORDER BY 字段, ... DESC
                                                            • 例: orderByDesc("id", "name")--->order by id DESC,name DESC

                                                            #orderBy

                                                            orderBy(boolean condition, boolean isAsc, R... columns)

                                                            image.gif

                                                              • 排序: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)

                                                              image.gif

                                                                • 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)

                                                                image.gif

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

                                                                  #or

                                                                  or()
                                                                  or(boolean condition)

                                                                  image.gif

                                                                    • 拼接 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)

                                                                    image.gif

                                                                      • OR 嵌套
                                                                      • 例: or(i -> i.eq("name", "李白").ne("status", "活着"))--->or (name = '李白' and status <> '活着')

                                                                      #and

                                                                      and(Consumer<Param> consumer)
                                                                      and(boolean condition, Consumer<Param> consumer)

                                                                      image.gif

                                                                        • AND 嵌套
                                                                        • 例: and(i -> i.eq("name", "李白").ne("status", "活着"))--->and (name = '李白' and status <> '活着')

                                                                        #nested

                                                                        nested(Consumer<Param> consumer)
                                                                        nested(boolean condition, Consumer<Param> consumer)

                                                                        image.gif

                                                                          • 正常嵌套 不带 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)

                                                                          image.gif

                                                                            • 拼接 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)

                                                                            image.gif

                                                                              • 无视优化规则直接拼接到 sql 的最后
                                                                              • 注意事项:
                                                                              • 只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用
                                                                              • 例: last("limit 1")

                                                                              #exists

                                                                              exists(String existsSql)
                                                                              exists(boolean condition, String existsSql)

                                                                              image.gif

                                                                                • 拼接 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)

                                                                                image.gif

                                                                                  • 拼接 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)

                                                                                  image.gif

                                                                                    • 设置查询字段
                                                                                    • 说明:
                                                                                    • 以上方法分为两类.
                                                                                      第二类方法为:过滤查询字段(主键除外),入参不包含 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)

                                                                                    image.gif

                                                                                      • SQL SET 字段
                                                                                      • 例: set("name", "老李头")
                                                                                      • 例: set("name", "")--->数据库字段值变为空字符串
                                                                                      • 例: set("name", null)--->数据库字段值变为null

                                                                                      #setSql

                                                                                      setSql(String sql)

                                                                                      image.gif

                                                                                        • 设置 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
                                                                                          }

                                                                                          image.gif

                                                                                          注意:这里的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)

                                                                                          image.gif

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

                                                                                          #用注解

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

                                                                                          image.gif

                                                                                          #用XML

                                                                                          List<MysqlData> getAll(Wrapper ew);

                                                                                          image.gif

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

                                                                                          image.gif

                                                                                          #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)

                                                                                          image.gif

                                                                                          #链式调用 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();

                                                                                          image.gif




                                                                                          Doker 技术人的数码品牌!!!

                                                                                          文章下方有交流学习区!一起学习进步!也可以前往官网,加入官方微信交流群!!!你的支持和鼓励是我创作的动力❗❗❗

                                                                                          官网:Doker 多克; 官方旗舰店首页-Doker 多克创新官方店-淘宝网全品8.5折优惠!!!

                                                                                          相关实践学习
                                                                                          如何在云端创建MySQL数据库
                                                                                          开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
                                                                                          全面了解阿里云能为你做什么
                                                                                          阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
                                                                                          目录
                                                                                          相关文章
                                                                                          |
                                                                                          SQL 关系型数据库 MySQL
                                                                                          Mybatis-plus4条件构造器方式
                                                                                          Mybatis-plus4条件构造器方式
                                                                                          50 0
                                                                                          |
                                                                                          SQL
                                                                                          MyBatis-Plus条件构造器之wapper介绍(一)
                                                                                          MyBatis-Plus条件构造器之wapper介绍
                                                                                          523 0
                                                                                          |
                                                                                          3天前
                                                                                          |
                                                                                          SQL Java 数据库连接
                                                                                          【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
                                                                                          MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。本文讲解了最新版MP的使用教程,包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段等核心功能。
                                                                                          【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
                                                                                          |
                                                                                          18天前
                                                                                          |
                                                                                          SQL 安全 Java
                                                                                          MyBatis-Plus条件构造器:构建安全、高效的数据库查询
                                                                                          MyBatis-Plus 提供了一套强大的条件构造器(Wrapper),用于构建复杂的数据库查询条件。Wrapper 类允许开发者以链式调用的方式构造查询条件,无需编写繁琐的 SQL 语句,从而提高开发效率并减少 SQL 注入的风险。
                                                                                          13 1
                                                                                          MyBatis-Plus条件构造器:构建安全、高效的数据库查询
                                                                                          |
                                                                                          6月前
                                                                                          |
                                                                                          SQL
                                                                                          【MybatisPlus】条件构造器、自定义SQL、Service接口
                                                                                          【MybatisPlus】条件构造器、自定义SQL、Service接口
                                                                                          98 0
                                                                                          【MybatisPlus】条件构造器、自定义SQL、Service接口
                                                                                          |
                                                                                          6月前
                                                                                          |
                                                                                          SQL 存储 算法
                                                                                          Mybatis-Plus- CRUD接口-主键策略-自动填充和乐观锁-分页-逻辑删除-条件构造器和常用接口
                                                                                          Mybatis-Plus- CRUD接口-主键策略-自动填充和乐观锁-分页-逻辑删除-条件构造器和常用接口
                                                                                          |
                                                                                          SQL 数据库
                                                                                          MyBatisPlus 之 条件查询 <条件构造器>
                                                                                          MyBatisPlus 之 条件查询 <条件构造器>
                                                                                          167 0
                                                                                          mysql-MybatisPlus的条件构造器
                                                                                          MybatisPlus的条件构造器
                                                                                          |
                                                                                          6月前
                                                                                          |
                                                                                          SQL XML Java
                                                                                          MyBatis Plus通用CRUD与条件构造器使用及SQL自动注入原理分析
                                                                                          MyBatis Plus通用CRUD与条件构造器使用及SQL自动注入原理分析
                                                                                          284 0
                                                                                          mybatisPlus条件构造器体系解读
                                                                                          mybatisPlus条件构造器体系解读