【问题标题】:For a JPA entity with many to 1 relation to a data entity, how to sort a list of objects by the result of a method call of the data entity?对于与数据实体具有多对一关系的JPA实体,如何根据数据实体的方法调用结果对对象列表进行排序?
【发布时间】:2022-01-14 14:05:33
【问题描述】:

我有一个 JPA 实体用户,其中包含与 UserStats 实体的 OneToMany 关系。我已经重构了现有代码以使用这个新的 UserStats 实体,并且之前为了管理与胜利率相关的功能,我将胜利率作为属性存储在 User 实体中。

但是,我认为最好让一个方法返回胜利比率,因此在 UserDetails 实体中实现了 calculateVictoryRatio()。

这导致了一些问题,例如,我在 UserRepo 中有一个存储库方法:

List<User> findAllByOrderByVictoryRatioDesc();

我不能再直接在 repo 中搜索这个,因为victoryRatio() 方法在 User 实体的 UserStats 中,而且我认为你不能在 repo 方法中调用方法?

所以我现在尝试在 userService 中做,但无法弄清楚:

public List<User> getBestVSUsers() {

    List<User> users = userRepository.findAll();
    for (User user: users
         ) {
        user.getUserStats().get(0).calculateVictoryRatio();
    }

}

但是,我需要根据calculateVictoryRatio()的结果对上面的列表进行排序。

我也在我的 React 前端渲染这个:

   const topUserList = users.map(user => {
            return <tr key={user.id}>
                <td style={{ whiteSpace: 'nowrap' }} class="player-list-key-text">{user.name}</td>
                <td className="player-list-key-text">{user.username}</td>
                <td className="player-list-key-text"><span className="defeats">{user.victories}</span></td>
                <td className="player-list-key-text"><span className="victories">{user.defeats}</span></td>
                <td className="player-list-key-text"><span className="victory-score">{user.victoryRatio}</span></td>
            </tr>
        });

我如何呈现以上的胜利比率、失败和胜利现在它们被封装在 UserStats 实体中?我是否需要单独提取并合并 2 个?或者我可以这样做:

{user.userStats[0].victories}

我该怎么做?有一个更好的方法吗?我可以在 userRepo 中调用方法吗?

感谢您的帮助

【问题讨论】:

  • 也许你可以在Pageable上使用自定义:stackoverflow.com/questions/33318257/…
  • @mEstrazulas 我可能只是在 UserStats 中再次将胜利分数设为属性字段,然后回到旧的方式。

标签: javascript java reactjs spring spring-boot


【解决方案1】:

试试这样的:

PageRequest pageRequest = new PageRequest(pageNumber, pageSize, new Sort(new Order(Direction.DESC, "ORDER BY (VICTORIES/DEFEATS)"))
Page page = myRepository.findAll(specification, pageRequest);

您可以在 ORDER BY 的哪个位置输入您的比率公式。在这种情况下,我们会将计算结果放在您的 SGDB 上。

【讨论】:

    【解决方案2】:

    只要您在查询中加入该实体,就可以对相关实体进行排序。您可能需要在存储库中定义自定义查询。

    @Query("SELECT u from User u JOIN u.userStats us ORDER BY us.victoryRatio")
    List<User> findAllCustomSort();
    

    但是,显然数据库引擎在此处进行排序,与您的代码无关。您还没有向我们展示您的 calculateVictory 方法的内容,但是如果您必须根据您在代码中执行的计算进行排序,那么它将不起作用。我怀疑是这种情况,因为您只是在谈论将比率移动到另一个实体,而不是开始计算它。但如果是这样,您当然可以始终只对内存中的列表进行排序。考虑到您没有使用分页,这也不会太糟糕。

    或者,如果您绝对必须在数据库中进行排序,那么我认为您别无选择,只能在数据库中为其创建自定义函数。不过,这会超出这个问题的范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 2012-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 2023-03-05
      相关资源
      最近更新 更多