在使用srpingboot2.x+mybatis-plus框架是遇到特殊需求時研究mybatis-plus的條件構造器動態拼接sql查詢,這個查詢接口涉及到了自定義sql,動態拼接sql,分頁,求和,分組,排序。
可以直接看業務實現方法
首先說一下接口的需求:
入參JSON:
1 { 2 "from": "2020-5-29", 3 "limit": 10, 4 "offset": 0, 5 "order": "hitCount", 6 "page": 1, 7 "search": "", 8 "sort": "desc", 9 "sortDirection": "", 10 "to": "2020-6-10" 11 }
入參注釋說明:
{ "from": "開始查詢時間", "limit": 條數, "offset": 0, "order": "需要排序的字段", "page": 頁碼, "search": "查詢條件", "sort": "排序規則", "sortDirection": "", "to": "結束查詢時間" }
然后先寫接口實現:
1 @PostMapping("categoryList") 2 public R getCategoryList(@Validated @RequestBody QaDetailSearchVo vo){ 3 RobotPage pageHelper = new RobotPage(vo.getPage(),vo.getLimit()); 4 return R.ok(iStatQaService.findQaStatCategory(pageHelper, vo)); 5 }
解釋:POST請求,R 是自定義的返回類型,RobotPage是為了實現一些特殊返回值 繼承於mybatsi-plus分頁的Ipage:
1 public class RobotPage<T> extends Page<T> implements Serializable {}
重點是業務實現類和mapper層:
對於一般的查詢mybatis-plus的條件構造器已經可以滿足了,例如:
1 SysUser sysUser = baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery() 2 .select(SysUser::getUserId, SysUser::getUsername, SysUser::getPhone, SysUser::getEmail, SysUser::getPassword, SysUser::getDeptId, SysUser::getJobId, SysUser::getAvatar) 3 .eq(SysUser::getUsername, username));
但是對於一些需要復雜的或者多表的操作就需要自定義sql語句了,示例:
首先是mapper自定義分頁查詢接口:
1 @Select("SELECT s.category_id as id, s.category_name as category, SUM(s.hit_count) as hitCount, SUM(s.solve_count) as resolvedCount, SUM(s.not_solve_count) as unresolvedCount " + 2 "FROM core_stat_qa as s ${ew.customSqlSegment}") 3 IPage<QaDetailCategoryListVo> findCategoryListByParams(IPage<QaDetailCategoryListVo> page, @Param(Constants.WRAPPER) QueryWrapper<StatQa> wrappers);
這部分官網給的有示例:https://mybatis.plus/guide/wrapper.html#%E4%BD%BF%E7%94%A8-wrapper-%E8%87%AA%E5%AE%9A%E4%B9%89sql
業務接口不用看 直接是實現類:
1 @Override 2 public Grid findQaStatCategory(Page<QaDetailCategoryListVo> page, QaDetailSearchVo vo) { 3 //聲明返回 4 Grid grid = new Grid(); 5 //組裝查詢語句 6 QueryWrapper<StatQa> qaQueryWrapper = new QueryWrapper<>(); 7 //模糊查詢 8 qaQueryWrapper.like(StringUtils.isNotBlank(vo.getSearch()),"category_name",vo.getSearch()); 9 //where條件 10 qaQueryWrapper.ge("create_time", DateUtil.parse(vo.getFrom(),"yyyy-MM-dd")); 11 qaQueryWrapper.lt("create_time",DateUtil.parse(vo.getTo(), "yyyy-MM-dd")); 12 //分組 13 qaQueryWrapper.groupBy("category_id","category_name"); 14 //排序 15 qaQueryWrapper.orderBy(true, !"desc".equals(vo.getSort()),vo.getOrder()); 16 //調用自定義sql語句 17 IPage<QaDetailCategoryListVo> statQaIPage = baseMapper.findCategoryListByParams(page, qaQueryWrapper); 18 //抽取list 19 List<QaDetailCategoryListVo> statQaList = statQaIPage.getRecords(); 20 grid.setList(statQaList); 21 grid.setTotal(statQaIPage.getTotal()); 22 return grid; 23 }
需要解釋的:
排序orderBy方法中的第一個true官網上也是給出解釋的:表示該條件是否加入最后生成的sql中。
!"desc".equals(vo.getSort()) 是排序規則 asc和desc
調用mapper自定義sql就是:
baseMapper.findCategoryListByParams(page, qaQueryWrapper);
接口完成。