030-若依pro(ruoyi-vue-pro)MyBatis 动态SQL与联表查询实战

张开发
2026/4/17 5:24:57 15 分钟阅读

分享文章

030-若依pro(ruoyi-vue-pro)MyBatis 动态SQL与联表查询实战
1. 若依Pro框架中的MyBatis动态SQL入门第一次接触若依Pro框架的开发者可能会被MyBatis的动态SQL功能惊艳到。这个功能就像是给SQL语句装上了智能大脑让它能够根据不同的条件自动调整查询语句。在实际项目中我经常用它来处理各种复杂的查询场景效果相当不错。动态SQL的核心在于if、where、choose这些标签。举个例子当我们需要根据用户输入的不同条件来查询用户列表时传统做法可能要写多个查询方法而使用动态SQL只需要一个方法就能搞定。在若依Pro中这个特性被大量应用在各种管理系统的查询功能中。select idselectUserList resultTypeAdminUserDO SELECT * FROM system_users where if testusername ! null and username ! AND username LIKE CONCAT(%, #{username}, %) /if if teststatus ! null AND status #{status} /if /where /select上面这段XML配置就是典型的动态SQL用法。where标签会自动处理条件之间的AND连接而if标签则根据条件是否存在来决定是否包含某段SQL。我在实际项目中发现这种写法不仅减少了代码量还让查询逻辑更加清晰。2. 动态SQL的进阶用法与实战技巧2.1 复杂条件组合处理在实际开发中我们经常会遇到更复杂的查询条件组合。比如需要同时处理时间范围、多状态筛选等场景。这时候choose标签就派上用场了。它类似于Java中的switch-case结构可以根据不同条件执行不同的SQL片段。select idselectComplexUserList resultTypeAdminUserDO SELECT * FROM system_users where choose when testuserType admin AND role_id IN (1, 2, 3) /when when testuserType vip AND vip_level 0 /when otherwise AND status 1 /otherwise /choose if teststartTime ! null and endTime ! null AND create_time BETWEEN #{startTime} AND #{endTime} /if /where /select2.2 动态字段与排序处理除了条件查询动态SQL还能处理字段选择和排序。比如在列表页面用户可能希望自定义显示的列或者按不同字段排序。这时候可以用trim和foreach标签来实现。select idselectUserWithFields resultTypemap SELECT trim suffixOverrides, id, username, if testfields.contains(email)email,/if if testfields.contains(phone)phone,/if /trim FROM system_users ORDER BY foreach itemitem indexindex collectionsortFields separator, ${item.field} ${item.order} /foreach /select这种写法我在用户管理系统中使用过效果非常好。前端可以灵活指定需要查询的字段和排序方式而后端不需要为每种组合都写单独的查询方法。3. 联表查询的两种实现方式3.1 传统XML方式实现联表在若依Pro中联表查询是处理复杂业务场景的利器。最传统的方式就是在XML中直接写JOIN语句。比如查询用户信息时同时获取部门名称select idselectUserWithDept resultTypeAdminUserDetailDO SELECT u.*, d.name AS deptName FROM system_users u LEFT JOIN system_dept d ON u.dept_id d.id where if testusername ! null AND u.username LIKE CONCAT(%, #{username}, %) /if /where /select这种方式简单直接适合相对固定的联表查询。我在早期项目中大量使用这种写法它的优点是性能可控可以精确优化SQL语句。3.2 使用MyBatis Plus Join实现联表若依Pro还集成了MyBatis Plus Join框架可以用Java代码的方式实现联表查询。这种方式更加面向对象适合喜欢Lambda表达式的开发者。public ListAdminUserDetailDO selectUserWithDept(String username) { return selectJoinList(AdminUserDetailDO.class, new MPJLambdaWrapperAdminUserDO() .selectAll(AdminUserDO.class) .selectAs(DeptDO::getName, AdminUserDetailDO::getDeptName) .leftJoin(DeptDO.class, DeptDO::getId, AdminUserDO::getDeptId) .like(username ! null, AdminUserDO::getUsername, username) ); }这种写法虽然需要一定的学习成本但熟悉后开发效率很高。我在最近的项目中更倾向于使用这种方式因为它能更好地利用IDE的代码提示和重构功能。4. 分页查询的优化实践4.1 基础分页实现分页查询是管理系统中最常见的需求之一。在若依Pro中可以通过MyBatis的XML方式实现基本分页select idselectUserPage resultTypeAdminUserDO SELECT * FROM system_users LIMIT #{pageNo}, #{pageSize} /select不过这种简单实现有个问题当数据量很大时性能会下降。我曾在处理百万级数据表时就遇到过这个问题。4.2 性能优化分页对于大数据量的分页可以使用基于游标的分页方式select idselectUserPageOptimized resultTypeAdminUserDO SELECT * FROM system_users WHERE id #{lastId} ORDER BY id LIMIT #{pageSize} /select这种分页方式利用了索引的有序性避免了传统LIMIT OFFSET在大偏移量时的性能问题。在实际项目中当分页深度超过100页时这种方法的性能优势非常明显。4.3 使用MyBatis Plus的分页插件若依Pro默认集成了MyBatis Plus的分页插件使用起来更加方便public PageResultAdminUserDO getUserPage(UserPageReqVO reqVO) { PageAdminUserDO page new Page(reqVO.getPageNo(), reqVO.getPageSize()); IPageAdminUserDO pageResult adminUserMapper.selectPage(page, Wrappers.AdminUserDOlambdaQuery() .like(StringUtils.isNotBlank(reqVO.getUsername()), AdminUserDO::getUsername, reqVO.getUsername()) ); return new PageResult(pageResult.getRecords(), pageResult.getTotal()); }这种方式会自动处理总数统计和分页逻辑开发效率很高。我在大多数标准分页场景中都使用这种方式。5. 动态SQL与联表查询的综合应用5.1 复杂报表查询案例在实际项目中我们经常需要实现一些复杂的报表查询。比如需要根据多种条件查询用户及其关联的部门、角色信息select idselectUserReport resultMapuserReportMap SELECT u.*, d.name AS dept_name, r.name AS role_name FROM system_users u LEFT JOIN system_dept d ON u.dept_id d.id LEFT JOIN system_user_role ur ON u.id ur.user_id LEFT JOIN system_role r ON ur.role_id r.id where if testdeptId ! null AND u.dept_id #{deptId} /if if testroleId ! null AND r.id #{roleId} /if if teststatus ! null AND u.status #{status} /if /where /select这种综合应用展示了动态SQL和联表查询的强大组合能力。我在开发数据分析功能时经常使用这种模式。5.2 性能优化建议在进行复杂联表查询时有几点性能优化建议尽量避免超过3张表的JOIN操作为所有JOIN条件字段建立索引只查询必要的字段不要使用SELECT *对于大数据量表考虑使用冗余字段代替部分JOIN操作我在实际项目中就曾通过优化联表查询将某个报表的查询时间从5秒降低到了0.5秒以内。关键是要理解业务需求找到最适合的查询方式。

更多文章