MybatisPlus使用Wrapper查询指定字段并添加字段函数处理,过滤字段查询,自定义写sql
程序员文章站
2022-04-15 20:42:20
...
前言:新公司老大不让写sql,郁闷了好几天。我总觉得xml里写sql效率应该很高呀。没办法,只能听话用MybatisPlus的CURD和Wrapper。
start:平时Wrapper大家都知道一般是加在where后的条件,但是我想灵活地写select后的字段怎么办呢:
- 本文基于MybatisPlus3.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后的内容,我暂时没找到,想单独set某个字段,只能传一整个实体类进去。
- 我暂时的解决办法是这样,各位谁知道能单独set的告诉我,文档的UpdateWrapper的set函数我试了,没试出来呀。
(吐槽:还非得说这样效率高,我就不信它调用这么多方法,new这么多对象,还有一些反射降低效率,最后还是拼成sql执行。难道我直接在mapper.xml里写一句sql效率比这样低???求大神解惑)
@DeleteMapping("/{id}") @ApiOperation("removeById") public ResponseResult<String> removeById(@PathVariable String id) { // 先查后存,保证只修改delState字段,其余的不变 ClientEncyArticles encyArticles = encyArticlesService.getById(id); encyArticles.setDelState(true); if (!encyArticlesService.updateById(encyArticles)) { throw RequestException.fail("删除失败"); } else { return ResponseResult.ok(); } }