postgresql QueryWrapper left join
原生的 MyBatis-PlusQueryWrapper不支持LEFT JOIN。QueryWrapper的设计初衷是用于单表的 CRUD 操作。它生成的 SQL 结构固定为SELECT ... FROM table WHERE ...无法直接生成JOIN子句。但是如果你需要在 MyBatis-Plus 中实现联查特别是结合你上一个问题中的 PostgreSQLLATERAL语法有以下3 种解决方案方案一使用 XML 映射文件最推荐功能最强如果你需要使用 PostgreSQL 特有的LEFT JOIN LATERAL语法或者联查逻辑比较复杂XML 是最佳选择。它保留了 MyBatis-Plus 的分页和基础功能同时允许你编写任意复杂的 SQL。1. Mapper 接口Mapper public interface ApplicationMapper extends BaseMapperApplication { // 自定义方法返回 DTO 而不是 Entity ListAppDetailDTO selectAppWithAttachment(IPage page, Param(ew) WrapperApplication wrapper); }2. XML 文件 (ApplicationMapper.xml)在这里你可以直接使用之前讨论的LATERAL语法并动态拼接QueryWrapper生成的 WHERE 条件。mapper namespacecom.example.mapper.ApplicationMapper select idselectAppWithAttachment resultTypecom.example.dto.AppDetailDTO SELECT a.id, a.title, att.file_url AS attachmentUrl FROM applications a !-- 这里可以自由写复杂的 PG 语法 -- LEFT JOIN LATERAL ( SELECT file_url FROM attachments WHERE app_id a.id ORDER BY created_at DESC LIMIT 1 ) att ON true !-- 动态拼接 QueryWrapper 的 WHERE 条件 -- ${ew.customSqlSegment} /select /mapper3. 调用PageAppDetailDTO page new Page(1, 10); QueryWrapperApplication wrapper new QueryWrapper(); wrapper.eq(a.user_id, 123); // 注意XML 中表别名要对应 // 调用自定义方法 applicationMapper.selectAppWithAttachment(page, wrapper);优点完全控制 SQL支持 PG 特性性能最好。缺点需要写 XML 文件。方案二使用增强插件mybatis-plus-join(最像 Wrapper)社区有一个非常流行的插件叫mybatis-plus-join(MpJ)它在QueryWrapper的基础上扩展了联查功能。1. 引入依赖dependency groupIdcom.github.yulichang/groupId artifactIdmybatis-plus-join/artifactId version1.4.0/version !-- 请检查最新版本 -- /dependency2. 代码使用// 使用 MpJoinWrapper 代替 QueryWrapper MpJoinWrapperApplication wrapper new MpJoinWrapper(); wrapper.select(Application::getId, Application::getTitle) .select(Attachment::getFileUrl) .leftJoin(Attachment.class, Attachment::getAppId, Application::getId) // 注意MpJ 默认可能不支持 LIMIT 1 的子查询逻辑 // 复杂的一对一取最新记录可能还是需要配合 apply 或 XML .orderByDesc(Attachment::getCreatedAt); // 查询 ListAppDetailDTO list applicationMapper.selectJoinList(page, wrapper, AppDetailDTO.class);优点链式调用无需 XML开发快。缺点对于“一对多取一条”如取最新附件这种逻辑原生 MpJ 处理起来可能不如LATERAL直观可能需要配合apply。方案三使用apply()方法硬拼 SQL (不推荐仅限简单场景)原生QueryWrapper提供了apply()方法可以注入原生 SQL 片段。QueryWrapperApplication wrapper new QueryWrapper(); wrapper.select(a.*, att.file_url) // 硬编码 JOIN 语句 .apply(LEFT JOIN attachments att ON a.id att.app_id) .eq(a.user_id, 123);严重缺点无法处理一对多取一条直接LEFT JOIN会导致申请记录膨胀一条申请对应多条附件结果集会有多行。SQL 注入风险apply中的参数如果拼接不当容易出问题。维护性差SQL 散落在 Java 代码中。不支持 PGLATERAL很难在apply里优雅地写子查询逻辑。关键提示结果映射 (DTO/VO)无论用哪种方式联查后的结果不能直接映射到Application实体类上因为实体类里没有attachment_url字段且一对多会导致数据重复。你需要创建一个DTO (Data Transfer Object)或VO (View Object)Data public class AppDetailDTO { private Long id; private String title; private String attachmentUrl; // 附件字段 }总结建议如果你必须用 PostgreSQL 的LATERAL优化取最新附件请使用方案一 (XML)。这是最稳妥、性能最好且能完整利用 PG 特性的方式。如果只是普通联查且不想写 XML可以尝试方案二 (mybatis-plus-join)。不要试图用原生QueryWrapper强行做复杂联查那是它的设计盲区。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2447836.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!