Spring JPA从子表和父表中选择几个字段

mkshixfv  于 2023-10-19  发布在  Spring
关注(0)|答案(1)|浏览(121)

下面有两个实体。

@Entity
public class Subscriber()
{
    int subId;
    String subName;
    String subAddress;
}

@Entity
public class Book()
{
    int bookId;
    int hiredBy; // -> References Subscriber.subId
    String bookName;    
}

下面有两个实体。当我在JPA中添加关系时,它从父表中获取所有列。相反,我希望在内部联接时只获取subName字段。有办法做到吗?

scyqe7ek

scyqe7ek1#

JPA通常处理实体和实体之间的关系。理想情况下,如果实体book依赖于Subscriber,则应该在book实体中定义关系。默认情况下,JPA会立即获取Subscriber实体,但您也可以延迟加载Subscriber

@Entity
public class Book()
{
    int bookId;

    @OneToOne
    @JoinColumn(name = "subId")
    Subscriber hiredBy;

    String bookName;
}

如果在查询实体Book时需要额外的字段,那么很可能需要DTO,因为我们不再只是查询Book entity

package com.stackoverflow;

class SubscriberBookDto {
    int bookId;
    int hiredBy;
    String hirerName;
    String bookName;

    public SubscriberBookDto(int bookId, int hiredBy, String hirerName, String bookName) {
        this.bookId = bookId;
        this.hiredBy = hiredBy;
        this.hirerName = hirerName;
        this.bookName = bookName;
    }
}

有多种方法可以构建此DTO。一种选择是查询Book实体并从它构造DTO。查询Book实体应该是一个不错的选择,尽管它会带来来自Subscriber的所有字段。
如果需要在后台进行更精细的SQL查询,那么最好查询数据库,只输入构建DTO所需的字段。它可能看起来像:

// in Book's jpa repository
@Query("select new com.stackoverflow.SubscriberBookDto(" +
        "book.id," +
        "subscriber.subId," +
        "subscriber.subName," +
        "book.name) " +
        "from Book book " +
        "inner join book.hiredBy subscriber ")
List<SubscriberBookDto> getBookSubscribers();

我觉得两个选择都不错。我更喜欢第一个,因为编写的代码更少,开销也很低。我建议在真正需要的时候在JPA级别上进行优化,否则这是一个过早的优化。

相关问题