SpringBoot存储库双向连接

时间:2020-01-22 10:00:38

标签: java hibernate spring-boot jpa

我有以下两个实体:

Driver.java

@Entity
@Table(name = "driver")
@Getter @Setter
public class Driver {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int dbid;

    private String lastName;

    private String firstName;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "driver")
    private List<Lap> laps;
}

Lap.java

@Entity
@Table(name = "lap")
@Getter @Setter
public class Lap {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer dbid;

    private Integer entryDbid;

    private Integer lapNumber;

    private Double lapTime;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "driver_dbid")
    @JsonIgnoreProperties("laps")
    private Driver driver;
}

现在我要创建两个存储库。一个用于选择所有具有相应圈数的驾驶员,另一个用于选择所有具有相应圈数的驾驶员的仓库。

LapRepository.java

public interface LapRepository extends JpaRepository<Lap, Integer> {

    @Query( value = "SELECT l, d FROM Lap l INNER JOIN l.driver d")
    List<Lap> findWithDriver();
}

DriverRepository.java

public interface DriverRepository extends JpaRepository<Driver, Integer> {

    @Query( value = "SELECT d FROM Driver d")
    List<Driver> findWithoutLaps();

    @Query( value = "SELECT d, l FROM Driver d INNER JOIN d.laps l")
    List<Driver> findWithLaps();
}

以下函数调用按预期方式工作。将仅执行一个查询,并将结果转换为Lap-Entity。

List<Lap> laps = this.lapRepository.findWithDriver() 

这里是日志:

1796761 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
2003707 nanoseconds spent preparing 1 JDBC statements;
58061128 nanoseconds spent executing 1 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)

如果我要执行以下操作:

List<Driver> drivers = this.driverRepo.findWithoutLaps()

它也按预期工作。这里出现n + 1问题,因为在查询中不会选择相应的圈数。

但是在这里: 列出驱动程序= this.driverRepo.findWithLaps()

我希望在查询期间选择相应的圈数,并将其设置在驾驶员对象上。 但是,我得到以下日志:

761869 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
2337819 nanoseconds spent preparing 87 JDBC statements;
305405297 nanoseconds spent executing 87 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
0 nanoseconds spent performing 0 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
0 nanoseconds spent executing 0 partial-flushes (flushing a total of 0 entities and 0 collections)

此外,对于每个结果行,各圈都被合并。 例如,这意味着: 我有50个驱动程序,每个驱动程序都有2个圈->结果中有100个驱动程序对象。

查询出了点问题,但是我不知道是什么?

编辑:这是postgres表:

驱动程序

dbid        serial    not null    primary key
first_name  text      not null
last_name   text      not null

膝部

dbid        serial    not null    primary key
entry_dbid  int       not null    foreign key
driver_dbid int       not null    foreign key
lap_number  int       not null
lap_time    double    not null

1 个答案:

答案 0 :(得分:0)

执行内部联合时,将同时使用两个表,就像在同一表中联接一样,您将复制寄存器。如果您使用DISTINCT,应该不会有问题

例如:

@Query( value = "SELECT DISTINCT d, l FROM Driver d INNER JOIN d.laps l")