MyBatis-Plus条件构造器实战指南从基础查询到安全防护记得第一次用MyBatis-Plus的EntityWrapper时我对着文档里的苍老师示例笑了半天但很快发现这个看似简单的工具背后藏着不少门道。今天咱们不聊段子只谈干货——如何用条件构造器写出既高效又安全的动态查询。1. 条件构造器基础从入门到精通刚接触MyBatis-Plus时EntityWrapper就像是一把瑞士军刀能解决各种查询场景。但要用好它得先理解几个核心概念字段引用原则与JPA不同EntityWrapper使用的是数据库字段名而非Java属性名。这个细节坑过不少新手// 错误示范 - 使用Java属性名 wrapper.eq(lastName, Tom); // 正确写法 - 使用数据库字段名 wrapper.eq(last_name, Tom);常用方法速查表方法名等效SQL适用场景eq()精确匹配ne()!不等于gt()/lt()/数值比较between()BETWEEN x AND y范围查询like()LIKE %x%模糊查询in()IN (x,y,z)多值匹配提示所有条件方法都支持链式调用但建议每行一个条件保持代码可读性2. 复杂查询构建OR条件的艺术当查询条件需要OR逻辑时or()和orNew()的区别就像咖啡和茶——看似相似实则大不同。来看个实际案例// 查询名字包含张或者年龄大于30的员工 ListEmployee employees employeeMapper.selectList( new EntityWrapperEmployee() .like(last_name, 张) .or() // 注意这个or的位置 .gt(age, 30) ); // 生成的SQL // SELECT * FROM employee WHERE (last_name LIKE %张% OR age 30)而orNew()会创建新的条件分组ListEmployee employees employeeMapper.selectList( new EntityWrapperEmployee() .eq(gender, 1) .orNew() // 新的条件组 .like(email, company.com) ); // 生成的SQL // SELECT * FROM employee WHERE (gender 1) OR (email LIKE %company.com%)何时用哪个需要简单OR逻辑时用or()需要明确分组条件时用orNew()复杂嵌套条件建议直接使用XML方式3. 排序与分页的陷阱分页查询是高频操作但有些用法暗藏风险// 危险示例 - 使用last()直接拼接SQL ListEmployee list employeeMapper.selectList( new EntityWrapperEmployee() .orderBy(create_time) .last(limit 10, 5) // SQL注入风险点 ); // 安全写法 - 使用Page对象 PageEmployee page new Page(2, 5); // 第2页每页5条 ListEmployee list employeeMapper.selectPage( page, new EntityWrapperEmployee().orderBy(create_time) );分页最佳实践始终优先使用Page对象避免直接拼接limit子句大数据量分页考虑使用PageHelper物理分页4. 安全防护远离SQL注入EntityWrapper虽然方便但某些方法可能成为安全漏洞。最典型的就是last()方法// 危险用户输入直接拼接 String userInput 1; DROP TABLE employee; --; wrapper.last(limit userInput); // 安全替代方案 wrapper.last(limit #{limit}, 10); // 使用参数化安全编码清单[ ] 禁用直接字符串拼接[ ] 对用户输入进行校验[ ] 使用最新版MyBatis-Plus3.x以上[ ] 考虑迁移到LambdaQueryWrapper5. 现代替代方案LambdaQueryWrapper新版MyBatis-Plus推荐使用LambdaQueryWrapper它有几个明显优势类型安全编译时检查字段名代码可读性更强避免拼写错误// 传统EntityWrapper写法 new EntityWrapperEmployee().eq(last_name, Tom); // LambdaQueryWrapper写法 new LambdaQueryWrapperEmployee().eq(Employee::getLastName, Tom);迁移建议新项目直接使用Lambda方式老项目逐步替换复杂查询可混合使用6. ActiveRecord模式简洁背后的代价ActiveRecord模式确实能让代码更简洁Employee employee new Employee(); employee.setLastName(张); ListEmployee list employee.selectList( new EntityWrapperEmployee().like(last_name, 张) );但要注意违反了单一职责原则可能造成实体类臃肿不利于复杂业务逻辑处理适用场景 ✓ 简单CRUD操作 ✓ 快速原型开发 ✓ 小型项目7. 性能优化小贴士在大数据量场景下这些技巧能提升查询效率索引命中确保条件字段有适当索引// 好的查询 - 能命中索引 wrapper.eq(department_id, 10).gt(salary, 5000); // 差的查询 - 无法使用索引 wrapper.like(%name, 张);**避免SELECT ***明确指定查询字段wrapper.setSqlSelect(id, name, email);批量操作使用专用批量方法// 低效 for(Employee e : list) { e.insert(); } // 高效 employeeMapper.insertBatch(list);在最近的一个用户管理系统项目中我们通过合理使用条件构造器将动态查询代码量减少了40%同时通过规范使用方式完全消除了SQL注入风险。特别是在处理多条件筛选面板时EntityWrapper的链式调用让代码既简洁又易维护。