当前位置: 首页 > news >正文

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 BaseMapper<Application> { // 自定义方法,返回 DTO 而不是 Entity List<AppDetailDTO> selectAppWithAttachment(IPage page, @Param("ew") Wrapper<Application> wrapper); }

2. XML 文件 (ApplicationMapper.xml)在这里你可以直接使用之前讨论的LATERAL语法,并动态拼接QueryWrapper生成的 WHERE 条件。

<mapper namespace="com.example.mapper.ApplicationMapper"> <select id="selectAppWithAttachment" resultType="com.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> </mapper>

3. 调用

Page<AppDetailDTO> page = new Page<>(1, 10); QueryWrapper<Application> 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> <groupId>com.github.yulichang</groupId> <artifactId>mybatis-plus-join</artifactId> <version>1.4.0</version> <!-- 请检查最新版本 --> </dependency>

2. 代码使用

// 使用 MpJoinWrapper 代替 QueryWrapper MpJoinWrapper<Application> 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); // 查询 List<AppDetailDTO> list = applicationMapper.selectJoinList(page, wrapper, AppDetailDTO.class);
  • 优点:链式调用,无需 XML,开发快。
  • 缺点:对于“一对多取一条”(如取最新附件)这种逻辑,原生 MpJ 处理起来可能不如LATERAL直观,可能需要配合apply

方案三:使用apply()方法硬拼 SQL (不推荐,仅限简单场景)

原生QueryWrapper提供了apply()方法,可以注入原生 SQL 片段。

QueryWrapper<Application> 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);
  • 严重缺点
    1. 无法处理一对多取一条:直接LEFT JOIN会导致申请记录膨胀(一条申请对应多条附件,结果集会有多行)。
    2. SQL 注入风险apply中的参数如果拼接不当,容易出问题。
    3. 维护性差:SQL 散落在 Java 代码中。
    4. 不支持 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; // 附件字段 }

总结建议

  1. 如果你必须用 PostgreSQL 的LATERAL优化(取最新附件):请使用方案一 (XML)。这是最稳妥、性能最好且能完整利用 PG 特性的方式。
  2. 如果只是普通联查且不想写 XML:可以尝试方案二 (mybatis-plus-join)
  3. 不要试图用原生QueryWrapper强行做复杂联查,那是它的设计盲区。
http://www.jsqmd.com/news/533839/

相关文章:

  • 2026年主数据厂商与数据拉通公司,优质服务实力推荐汇总 - 品牌2026
  • nli-distilroberta-base惊艳效果:中英文混合句子对推理准确率超89.2%
  • 批量分别压缩工具:支持随机密码、并行压缩和排除规则的批量打包方案
  • 【实战】Python+Bluez BLE广播开发:从零构建可被发现的自定义设备
  • Unity游戏毕业设计论文实战指南:从原型开发到技术文档撰写
  • 如何用TileLang实现高性能GPU算子:从入门到精通的完整指南
  • Flink项目实战篇 基于Flink的智慧交通实时预警系统(上)
  • 2026雅思写作备考app推荐:前考官力荐的提分神器 - 品牌2025
  • 【技术实践解析】SAM-Adapter:如何让“分割一切”模型在特定场景下表现更佳
  • 4步搞定RealSense SR300相机Ubuntu连接:Python深度相机开发终极指南
  • Citrix敦促用户修补允许未认证数据泄露的关键NetScaler漏洞
  • 长期合作的石英仪器厂家哪家好,东华石英性价比高不,费用多少? - 工业推荐榜
  • 别再只用编码器了!用ROS的robot_localization包融合IMU与Odom,让你的Cartographer建图精度翻倍
  • Keynote转PPT全攻略:Mac用户必知的5个高效技巧(含格式保留秘诀)
  • 伏羲天气预报开源可部署:支持离线环境+国产操作系统(OpenEuler)适配
  • eNSP毕设企业网入门实战:从零搭建高可用园区网络架构
  • Windows热键冲突终结者:Hotkey Detective完全指南
  • 从检测到理解:构建基于YOLOv5、DeepSORT与SlowFast的智能视频行为分析引擎
  • Kaetram-Open:构建2D MMORPG的开源引擎框架 | 开发者的多人游戏开发解决方案
  • 【技术解析】API如何成为现代数字生态系统的核心枢纽?
  • Anaconda虚拟环境详解:以Obspy安装为例教你管理Python依赖
  • 《风爆远征英雄年代怀旧服》官方网站:3月25日开服,老玩家直呼爷青回的经典国战
  • Claude中Skill的实现原理:是调用微调模型还是另有玄机?
  • 智能语音客服Agent架构图实战:从设计到高并发优化
  • Pixel Fashion Atelier快速部署:支持Windows/Linux/macOS多平台方案
  • Qwen3.5-4B-Claude-Opus效果展示:系统架构图文字描述→模块化要点提取
  • Pixel Mind Decoder 生成创意写作:基于情绪引导的诗歌与故事生成
  • 西门子1200PLC模板通讯程序模板案例:一站式解决多种通讯协议问题
  • 像素幻梦在教育场景落地:中小学数字美术课AI像素创作教学实践
  • 数据库因坏块导致无法VACUUM FREEZE问题处理