MyBatis Plus应用实践总结

简介: MyBatis Plus应用实践总结

【1】MyBatis Plus中的嵌套查询


很多时候我们可能需要构造一个嵌套查询,如WHERE (name = ? AND ( (id = ? OR type = ?) ))。外层是and(or)连接,嵌套一个or(and)查询。MyBatis Plus同样对此提供了支持,在Nested<Param, Children>接口中我们可以看到具体使用方法。

① Nested<Param, Children>接口源码

public interface Nested<Param, Children> extends Serializable {
//jdk1.8中支持了default方法,如下是and嵌套
    default Children and(Consumer<Param> consumer) {
        return this.and(true, consumer);
    }
//带条件的and嵌套
    Children and(boolean condition, Consumer<Param> consumer);
//or嵌套
    default Children or(Consumer<Param> consumer) {
        return this.or(true, consumer);
    }
//带条件的or嵌套
    Children or(boolean condition, Consumer<Param> consumer);
//不带and or的普通嵌套
    default Children nested(Consumer<Param> consumer) {
        return this.nested(true, consumer);
    }
//不带条件的不带and or的普通嵌套
    Children nested(boolean condition, Consumer<Param> consumer);
}


那么如何使用呢?这里建议有lambda表达式基础。


② 嵌套应用实例

如我们要达到的SQL效果为:WHERE (name = ? AND ( (id = ? OR type = ?) ))

第一种写法


这种写法比较麻烦,相当于实现了一个匿名类。

QueryWrapper<SysUser> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("name","jane");
queryWrapper.and(new Consumer<QueryWrapper<SysUser>>() {
    @Override
    public void accept(QueryWrapper<SysUser> sysUserQueryWrapper) {
        sysUserQueryWrapper.eq("id",1).or().eq("type",0);
    }
});

第二种写法使用lambda表达式

QueryWrapper<SysUser> queryWrapper=new QueryWrapper<>();
queryWrapper.eq("name","jane");
queryWrapper.and(e-> e.eq("id",1).or().eq("type",0));

这种确实很简洁了。

但是是用and嵌套需要注意的是and里面的查询条件不能为空,否则将会查询不到数据。示例如下:

 queryWrapper.eq(categoryId!=null,"category_id",categoryId);
 queryWrapper.and(e->e.like(!StringUtils.isEmpty(vagueParam),"title",vagueParam).or()
                    .like(!StringUtils.isEmpty(vagueParam),"theme",vagueParam));

当categoryId存在但是vagueParam为空的时候解析后的SQL如下所示:

where category_id=1 and (null)

这时是查询不到数据的,而MBP(MyBatis Plus)没有规避这种问题,故而需要程序员自行规避这个问题。


如果or里面有and呢?比如下面这个avg_price

WHERE
(
  field0 IN (?,?,?)and
  AND (
    (
      avg_price <= ?
      OR (
        (
          avg_price <= ?
          AND avg_price >= ?
        )
      )
      OR (
        (
          avg_price <= ?
          AND avg_price >= ?
        )
      )
    )
  )
)

这时我们采用Children or(Consumer<Param> consumer)方法:

// 人均费用
if(!StringUtils.isEmpty(totalPrice)){
    queryWrapper.and(
            e->{
                if(totalPrice.contains("999")){
                    e.le("avg_price",999).or();
                }
                if(totalPrice.contains("2999")){
                    e.or(e1->e1.le("avg_price",2999).ge("avg_price",1000)).or();
                }
            }
    );
}
default Children or(Consumer<Param> consumer) {
     return or(true, consumer);
 }

【2】UpdateWrapper

更新时候使用。

① update(Wrapper<T> updateWrapper)

这里以eq…set为例说明,eq作为更新条件,set为字段赋值。实例代码如下:

UpdateWrapper<SysOrderItem> updateWrapper=new UpdateWrapper();
updateWrapper.eq("order_id",1).set("state",1);
orderItemService.update(updateWrapper);

SQL如下:

UPDATE yihuiyuan.tb_sys_order_item SET state=? WHERE (order_id = ?) 

② update(T entity, Wrapper<T> updateWrapper)

前面entity都被封装为set属性,后面的updateWrapper则如①一样被正常解析。

实例代码如下:

UpdateWrapper<SysOrderItem> updateWrapper=new UpdateWrapper();
updateWrapper.eq("order_id",1).set("state",1);
SysOrderItem sysOrderItem=new SysOrderItem();
sysOrderItem.setNumber(10);
orderItemService.update(sysOrderItem,updateWrapper);

SQL如下:

UPDATE tb_sys_order_item SET number=?, state=? WHERE (order_id = ?) 

这里需要注意的是如果entity里面有字段和updateWrapper中set字段一样,则会出现重复,这时SQL执行效果为以后面的state为主:

UpdateWrapper<SysOrderItem> updateWrapper=new UpdateWrapper();
updateWrapper.eq("order_id",1).set("state",1);
SysOrderItem sysOrderItem=new SysOrderItem();
sysOrderItem.setNumber(10);
//如下也设置state属性
sysOrderItem.setState(10);
orderItemService.update(sysOrderItem,updateWrapper);

SQL如下:

UPDATE tb_sys_order_item SET number=?, state=?, state=? WHERE (order_id = ?) 
目录
相关文章
|
SQL Java 数据库连接
MyBatis 框架入门理论与实践
MyBatis 框架入门理论与实践
161 6
|
Java 数据库连接 mybatis
Mybatis Plus保存数据返回主键id
Mybatis Plus保存数据返回主键id
525 1
|
3月前
|
SQL Java 数据库
解决Java Spring Boot应用中MyBatis-Plus查询问题的策略。
保持技能更新是侦探的重要素质。定期回顾最佳实践和新技术。比如,定期查看MyBatis-Plus的更新和社区的最佳做法,这样才能不断提升查询效率和性能。
163 1
|
8月前
|
SQL Java 数据库连接
【潜意识Java】深入理解MyBatis,从基础到高级的深度细节应用
本文详细介绍了MyBatis,一个轻量级的Java持久化框架。内容涵盖MyBatis的基本概念、配置与环境搭建、基础操作(如创建实体类、Mapper接口及映射文件)以及CRUD操作的实现。此外,还深入探讨了高级特性,包括动态SQL和缓存机制。通过代码示例,帮助开发者更好地掌握MyBatis的使用技巧,提升数据库操作效率。总结部分强调了MyBatis的优势及其在实际开发中的应用价值。
198 1
|
Java 数据库连接 数据库
Spring Boot与MyBatis的集成应用
Spring Boot与MyBatis的集成应用
|
Java 数据库连接 测试技术
mybatis plus 获取新增实体的主键
mybatis plus 获取新增实体的主键
283 8
|
Java 数据库连接 数据库
mybatis plus 更新值为null的字段
mybatis plus 更新值为null的字段
196 7
|
Java 数据库连接 Spring
搭建 spring boot + mybatis plus 项目框架并进行调试
搭建 spring boot + mybatis plus 项目框架并进行调试
354 4
|
SQL Java 数据库连接
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
idea中配置mybatis 映射文件模版及 mybatis plus 自定义sql
426 3
|
Java 数据库连接 数据库
mybatis plus 中增删改查及Wrapper的使用
mybatis plus 中增删改查及Wrapper的使用
585 3