微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

仅从 Spring Data JPA 中的连接表多对多中选择特定列

如何解决仅从 Spring Data JPA 中的连接表多对多中选择特定列

目的是从连接表(多对多)中选择列。
我的问题是从连接的多对多表中选择两列。

我使用的是 Springboot 2.3 和 Spring 数据 Jpa。

我有这个数据模型,我想获取的是蓝色框框

model

所以本机查询可能看起来像这样(如果我是对的......)

SELECT bg.id,bg.name,p.name,c.name,c.short_desc FROM boardgame as bg 
 JOIN boardgame_category bgc on bg.id = bgc.fk_game 
 JOIN publisher p on bg.fk_publisher = p.id 
 JOIN category c on bgc.fk_category = c.id 
 WHERE bg.id = :id 

我第一次尝试在 JPQL 语句中使用 dto

public class BoardgameDto {

    private long id;

    private String name;

    private String publisherName;

    private Set<CatregoryDto> categoryDto;

    // setter,getter etc...
}

public class CategoryDto {

    private String name;

    private String shortDesc;

    // setter,getter etc...
}

JQPL 查询可能看起来像这样,但它不起作用(IDE 在 CategoryDto 上显示错误

/* THIS DOESN'T WORK */
SELECT new org.moto.tryingstuff.dto.BoardgameDto(bg.id,new org.moto.tryingstuff.dto.CategoryDto(c.name,c.short_desc)) FROM Boardgame as bg,Publisher as p,Category as c

好吧,我认为这种方式的问题在于 dto 的构造函数无法接收集合 as written here,而且我认为参数中的其他构造函数都没有。

然后我开始研究标准查询,特别是多选、元组、Dto,但看起来我遇到了同样的问题,所以我没有深入研究。

最后我使用了一个 JpaRepository 和它的 findById() 方法

public interface BoardgameRepository extends JpaRepository<Boardgame,Long> {
}

// In a test or service method
Boardgame game = repository.findById(long id);

然后我通过服务或控制器层中的映射过滤我需要保留的字段。所以前端只接收到需要的数据。

但是感觉有点矫枉过正,
我是否遗漏了什么,框架的任何部分都允许我只选择特定的列?

解决方法

如您所写,您不能使用集合作为构造函数表达式的参数。这是因为表达式被应用于结果集中的每条记录。这些记录是平面数据结构。它们不包含任何集合。您的数据库会为该集合中的每个元素返回一条新记录。

但是您的 constructor expression 因其他原因而失败。您正在尝试组合 2 个构造函数表达式,但不受支持。您需要删除第二个表达式并在 DTO 的构造函数中执行该操作。

因此,您的查询应如下所示:

SELECT new org.moto.tryingstuff.dto.BoardgameDto(bg.id,bg.name,p.name,c.name,c.short_desc) FROM Boardgame as bg <Your JOIN CLAUSES HERE>

你的 BoardgameDto 的构造函数是这样的:

public class BoardgameDto {

  public BoardgameDto(Long id,String gameName,String publisherName,String categoryName,String description) {
     this.id = id;
     this.name = gameName;
     this.publisherName = publisherName;
     this.category = new Category(categoryName,description);
  }

  ...
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。