java—在SpringDataJPA中仅从联接表(多对多)中选择特定列

kpbpu008  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(315)

其目的是从联接表(多对多)中选择列。
我的问题是从一个连接的多对多表中选择两列。
我使用的是springboot2.3和springdatajpa。
我有这个数据模型,我想获取的是蓝框字段

因此本机查询可以如下所示(如果我是对的话…)

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 statment中使用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, bg.name, p.name, 
new org.moto.tryingstuff.dto.CategoryDto(c.name, c.short_desc)) FROM Boardgame as bg, Publisher as p, Category as c

好吧,我认为这种方法的问题是dto的构造函数不能像这里写的那样接收集合,而且我认为参数中的另一个构造函数也不能。
然后我开始研究criteria查询,特别是multiselect、tuple、dto,但看起来我也有同样的问题,所以我没有深入研究。
最后我使用了一个jparepository,它的findbyid()方法如下

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

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

然后通过服务层或控制器层中的Map过滤需要保留的字段。所以前线只收到需要的数据。
但感觉有点过分了,
我是否遗漏了什么,框架中允许我只选择特定列的任何部分?

6ojccjat

6ojccjat1#

在编写时,不能将集合用作构造函数表达式的参数。这是因为表达式应用于结果集中的每个记录。这些记录是一个扁平的数据结构。它们不包含任何集合。数据库将为集合中的每个元素返回一个新记录。
但构造函数表达式失败的原因不同。您正在尝试组合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>

你棋盘游戏的构造器是这样的:

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);
  }

  ...
}

相关问题