对 Sports Player 进行建模并使用 Spring Data JPA 进行查询

问题描述 投票:0回答:1

我在 Spring Boot 中使用 Spring Data JPA 有一个数据 model,称为 Player。这代表体育运动中的一个人,该球员有一个名为 jerseyNumber (数字)和位置(他在哪里打球、中锋、防守等)的属性。随着他职业生涯的发展,这些属性具有不同的价值。一个赛季他打8号球,另一个赛季打7号球。

Player name 1
jerseyNumber 8 - Position center - 01.01.2020-31.12.2020
jerseyNumber 7 - Position attacker - 01.01.2021-Present

如何设置 Spring Data JPA 来处理我想知道特定日期的确切状态的查询?假设我想知道 2020 年 6 月 1 日模型的详细信息。

我正在使用 Postgres

这是我认为的一个选择。
我省略了从存储库中提取播放器并计算当前状态的服务代码。基本上遍历每个字段并根据提供的时间戳确定当前状态,并从中返回一个单独的 DTO 模型。这是一个好方法吗?
我有点担心这些是我最需要急切执行的连接查询。我正在考虑将此数据存储在玩家表中的 JSONB 列中。我的 API 需要在一次响应中为潜在的一百名玩家提供服务。这个示例有点简化,因为这种模式也存在于应用程序中的不同实体周围(查询哪些球队在特定时间点拥有哪些球员等)

@Entity
public class Player {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "player")
    private List<PlayerNumber> playerNumbers = new ArrayList<>();

    // Getters and setters
}
@Entity
public class PlayerNumber {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private int number;
    private LocalDate startDate;
    private LocalDate endDate;

    @ManyToOne
    private Player player;

    // Getters and setters
}
java oop database-design spring-data-jpa
1个回答
0
投票

我想说你的数据模型是一个很好的方法,但是通过使用服务或急切加载在特定时间点获取玩家的想法不是。 我们会解决您关心的每一个问题。

  1. 用于获取特定时间点的玩家的 SQL 查询。
select *
from player_number pn
join player p on pn.player_id = p.id
where pn.start_date < :date
and (pn.end_date > :date or pn.end_date is null) // Suspect null is present
  1. 使用
    spring-data-jpa
    有多种方法可以实现这一点,请参考这个doc示例
public interface PlayerNumberRepository extends JpaRepository<PlayerNumber, Long> {

    @Query("SELECT p FROM PlayNumber p WHERE p.startTime <= ?1 and (p.endTime >= ?1 or p.endTime is null)")
    List<FuelPrice> findInSpecificPointInTime(LocalDate pointInTime);
}
  1. 您想要通过多个连接获得结果,您可以使用
    Proxy projection
    又名自定义 dto,也可以应用分页。示例
public interface PlayerDto {
    Long getId();
    int getNumber();
    // All getters properties
}

并将其应用到存储库

public interface PlayerNumberRepository extends JpaRepository<PlayerNumber, Long> {

    @Query(nativeQuery = true,
value="select p.id as id, pn.number as number
from player_number pn
join player p on pn.player_id = p.id
where pn.start_date < :date
and (pn.end_date > :date or pn.end_date is null)")
    List<PlayerDto> findInSpecificPointInTime(LocalDate pointInTime);
}

这是示例,希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.