🍬🍬🍬文章目录
前言:新公司老大不让写sql,郁闷了好几天。我总觉得xml里写sql效率应该很高呀。没办法,只能听话用MybatisPlus的CURD和Wrapper。
begin:平时Wrapper大家都知道一般是加在where后的条件,但是我想灵活地写select后的字段怎么办呢?
- 本文基于MybatisPlus==3.0.6==
- 首先推荐大家学习一定要看文档,点我
- ==大前提==:CURD的执行接口需要有Wrapper传参,比如
list(Wrapper<T> queryWrapper) -- page(IPage<T> page -- Wrapper<T> queryWrapper) -- listObjs(Wrapper<T> queryWrapper)
等(我并没有一个一个试,用的时候大家试一下) - 这里没有写的很详细,因为时间有限,如果有看不大明白的,文章最后有我的群号欢迎讨论
- 以下代码我LambdaQueryWrapper和QueryWrapper混用的,这里用Lambda的好处就是降低代码的耦合性,不需要把字段名写死,但是不利于添加函数处理。懂得不要奇怪,不懂得留言或者进群讨论。
- 文档:过滤查询字段(主键除外),入参不包含 class 的调用前需要wrapper内的entity属性有值! 指定字段查询和过滤字段查询这两类方法重复调用以最后一次为准,指定查询和过滤查询不会同时存在
🍬 01. 只查询指定字段
- 使用select(字段1,字段2....)
.select(ClientBanner::isDelState,ClientBanner::getBusinessId);
public List<ClientBanner> getListById(String businessId) { LambdaQueryWrapper<ClientBanner> wrapper = new LambdaQueryWrapper(); // 商家图片,未删除,可用状态 wrapper.eq(ClientBanner::getBusinessId,businessId) .eq(ClientBanner::isDelState,false) .eq(ClientBanner::isUsable,true) .select(ClientBanner::isDelState,ClientBanner::getBusinessId); List<ClientBanner> list = this.list(wrapper); return list; }
- 控制台打印
: ==> Preparing: SELECT del_state,business_id FROM client_banner WHERE business_id = ? AND del_state = ? AND usable = ? : ==> Parameters: 55456(String), false(Boolean), true(Boolean) : <== Total: 2
- 不用LambdaQueryWrapper的方式为: 02. 对查询字段进行函数处理
🍬 02. 对查询字段进行函数处理
- 使用QueryWrapper,传入数据库字段的时候加上函数
"left(content,2) content"
这种函数处理,==如果你是用封装的对象接收,别忘了起别名==public IPage<ClientEncyArticles> listBySplitPage(SplitPageDTO dto) { QueryWrapper<ClientEncyArticles> wrapper = new QueryWrapper<ClientEncyArticles>(); wrapper.eq("del_state",false) .orderByDesc("create_time") .select("id","author","left(content,2) content","cover_picture","create_time"); IPage<ClientEncyArticles> page = this.page(new Page<>(dto.getPage(), dto.getPageSize()), wrapper); return page; }
- 控制台打印
: ==> Preparing: SELECT id,author,left(content,2),cover_picture,create_time FROM client_ency_articles WHERE del_state = ? ORDER BY create_time DESC LIMIT ?,? : ==> Parameters: false(Boolean), 0(Long), 10(Long) : <== Total: 10
🍬 03. 排除指定(过滤)字段查询
- 文档:过滤查询字段(主键除外),入参不包含 class 的调用前需要wrapper内的entity属性有值! 指定字段查询和过滤字段查询这两类方法重复调用以最后一次为准,指定查询和过滤查询不会同时存在
- 即过滤查询不能过滤主键
- 使用过滤查询时需要传clsss参数或者用setEntity方法,目的就是把实体传过去。看下面代码
- 使用select(i->!i.())
.select(i->!i.getProperty().equals("delState"));
或者.select(i->!i.getColumn().equals("del_state"));
- 别忘了
!
非号,如果不加!
就是指定字段查询,这种指定字段查询不如 01. 只查询指定字段 & 02. 对查询字段进行函数处理 简便
public IPage<ClientEncyArticles> listBySplitPage(SplitPageDTO dto) { ClientEncyArticles cc = new ClientEncyArticles(); QueryWrapper<ClientEncyArticles> wrapper = new QueryWrapper<ClientEncyArticles>(); wrapper.eq("del_state",false) //.setEntity(new ClientEncyArticles()) //如果下边参数不写ClientEncyArticles.class,这里要加setEntity .orderByDesc("create_time") // .select(ClientEncyArticles.class,i->!i.getColumn().equals("del_state")); // 填的是数据库字段名 .select(ClientEncyArticles.class,i->!i.getProperty().equals("delState")); // 填的是实体类字段名,个人认为用这个好一些 IPage<ClientEncyArticles> page = this.page(new Page<>(dto.getPage(), dto.getPageSize()), wrapper); return page; }
- 别忘了
- 控制台打印
==> Preparing: SELECT id,author,type,content,cover_picture,create_time FROM client_ency_articles WHERE del_state=? AND del_state = ? ORDER BY create_time DESC LIMIT ?,? ==> Parameters: false(Boolean), false(Boolean), 0(Long), 10(Long) <== Total: 10
🍬拓:自定义where后的所有内容,直接写sql
- 文档:last函数 无视优化规则直接拼接到sql的最后,这样select按照本文上边的方法自定义,剩下的直接last函数开搞(也不懂源码,不知道无视他的优化规则会发生啥,自己注意sql的效率应该没啥问题)
🍬单独set某个字段
文档链接,官方源码:
例: