SpringBoot项目实战:用MyBatis-Plus-Join搞定多表联查(附完整代码)
SpringBoot实战MyBatis-Plus-Join实现高效多表联查全攻略在业务系统开发中多表联查是绕不开的刚需场景。传统MyBatis需要手动编写复杂SQL而MyBatis-Plus-Join简称MPJ的出现让Java开发者能够用面向对象的方式优雅处理关联查询。本文将带你从零构建一个用户-部门联查系统完整覆盖环境搭建、注解配置、CRUD操作等实战要点。1. 环境准备与项目初始化1.1 创建SpringBoot项目使用Spring Initializr创建项目时需勾选以下依赖Spring WebLombokMySQL Driver然后在pom.xml中追加MPJ核心依赖dependency groupIdcom.github.yulichang/groupId artifactIdmybatis-plus-join-boot-starter/artifactId version1.4.11/version /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.5/version /dependency1.2 数据库配置application.yml中配置数据源和MP基本参数spring: datasource: url: jdbc:mysql://localhost:3306/mpj_demo?useSSLfalse username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 02. 实体与Mapper设计2.1 实体类注解配置用户实体SysUser.java示例Data TableName(sys_user) public class SysUser { TableId(type IdType.AUTO) private Long id; private Long deptId; private String userName; private String nickName; TableField(exist false) private String deptName; // 非数据库字段用于接收联查结果 }部门实体SysDept.java配置一对一关联Data TableName(sys_dept) public class SysDept { TableId(type IdType.AUTO) private Long id; private String deptName; }2.2 Mapper接口继承链用户Mapper需继承MPJBaseMapperpublic interface SysUserMapper extends MPJBaseMapperSysUser { }Service层同样需要特殊继承public interface ISysUserService extends MPJBaseServiceSysUser { }3. 联表查询实战技巧3.1 基础左连接查询实现用户列表带部门名称的查询public ListUserDTO getUserListWithDept() { MPJLambdaWrapperSysUser wrapper new MPJLambdaWrapper() .selectAll(SysUser.class) .select(SysDept::getDeptName) .leftJoin(SysDept.class, SysDept::getId, SysUser::getDeptId); return sysUserService.selectJoinList(UserDTO.class, wrapper); }注意UserDTO需要包含SysUser所有字段deptName属性3.2 复杂条件分页查询带条件的分页联查示例public PageUserDTO searchUsers(SearchParam param) { MPJLambdaWrapperSysUser wrapper new MPJLambdaWrapper() .selectAs(SysDept::getDeptName, UserDTO::getDeptName) .leftJoin(SysDept.class, SysDept::getId, SysUser::getDeptId) .like(param.getKeyword() ! null, SysUser::getNickName, param.getKeyword()) .eq(param.getDeptId() ! null, SysUser::getDeptId, param.getDeptId()); return sysUserService.selectJoinPage(new Page(param.getPage(), param.getSize()), UserDTO.class, wrapper); }3.3 一对多关联查询查询部门及其下属用户public ListDeptVO getDeptWithUsers() { MPJLambdaWrapperSysDept wrapper new MPJLambdaWrapper() .selectAll(SysDept.class) .selectCollection(SysUser.class, DeptVO::getUserList) .leftJoin(SysUser.class, SysUser::getDeptId, SysDept::getId); return sysDeptService.selectJoinList(DeptVO.class, wrapper); }4. 联表增删改高级应用4.1 关联更新操作同时更新用户和部门信息public boolean updateUserAndDept(Long userId) { UpdateJoinWrapperSysUser wrapper JoinWrappers.update(SysUser.class) .set(SysUser::getNickName, 新昵称) .set(SysDept::getDeptName, 新部门名) .leftJoin(SysDept.class, SysDept::getId, SysUser::getDeptId) .eq(SysUser::getId, userId); return sysUserService.updateJoin(null, wrapper); }4.2 关联删除方案根据条件删除主表数据public boolean deleteUserWithCondition(Long deptId) { DeleteJoinWrapperSysUser wrapper JoinWrappers.delete(SysUser.class) .leftJoin(SysDept.class, SysDept::getId, SysUser::getDeptId) .eq(SysDept::getId, deptId); return sysUserService.deleteJoin(wrapper); }级联删除关联表数据public boolean cascadeDelete(Long userId) { DeleteJoinWrapperSysUser wrapper JoinWrappers.delete(SysUser.class) .deleteAll() .leftJoin(SysDept.class, SysDept::getId, SysUser::getDeptId) .eq(SysUser::getId, userId); return sysUserService.deleteJoin(wrapper); }5. 性能优化与踩坑指南5.1 N1查询问题解决MPJ默认使用LEFT JOIN一次性加载数据但需要注意避免selectAll()在多层关联时使用复杂关联建议拆分为多次查询大数据量时添加Transactional注解5.2 缓存配置建议在MybatisConfig中增加二级缓存Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 添加缓存插件 interceptor.addInnerInterceptor(new CachingInnerInterceptor()); return interceptor; }5.3 常见问题排查字段映射失败检查DTO属性与selectAs别名是否一致确认表字段是否有下划线转驼峰问题分页总数不准复杂联查建议使用SqlParser(filtertrue)或者手动指定countSql事务失效场景跨Service调用需要添加Transactional批量操作建议使用TransactionTemplate实际项目中在处理用户-角色-权限三级关联时MPJ的链式API比传统XML方式减少约60%的代码量。特别是在动态条件查询场景Wrapper的条件构造方式让复杂查询的维护成本大幅降低。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2438984.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!