标准 Jpa Select 外国实体

Criteria Jpa Select foreign entity

任何人都可以帮助将此 hsql 转换为条件,请:

Select S From Player P Inner Join P.setting S Where P.id = :pid

我在处理这个查询时感到困惑。

即使你在做一个 JOIN,从你的变量名来看,我觉得你在 PlayerSetting 之间建立了一个 @OneToOne 关系,是吗?

如果您为 @OneToOne 关系建模Setting 将在 Player 加载时自动加载。这意味着您可以执行简单的 em.find(Player.class, pid) 并使用 player.getSetting() 来访问它。如果您仍想使用条件 API,请继续

public Player findByPlayerId(Long pid){
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Player> cq = cb.createQuery(Player.class);
    Root<Player> playerRoot = cq.from(Player.class);
    cq.select(playerRoot);
    cq.where(cb.equal(playerRoot.<Long>get("id"),cb.parameter((Long.class), "playerId")));
    TypedQuery<Player> tq = em.createQuery(cq);
    tq.setParameter("playerId", pid);
    return tq.getSingleResult();        
}

如果您对从 Player 指向 Setting@OneToMany 关系建模,您可能会执行 JOIN,因为映射是延迟加载的.在您使用条件 API 的情况下,可以这样做:

public List<Setting> getSettingsByPlayerId(Long pid){
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Setting> cq = cb.createQuery(Setting.class);
    Root<Player> playerRoot = cq.from(Player.class);
    Join<Player, Setting> joinedSettings = playerRoot.join("setting"); //or better settings with an 's'
    cq.select(joinedSettings);
    cq.where(cb.equal(playerRoot.<Long>get("id"),cb.parameter((Long.class), "playerId")));      
    TypedQuery<Setting> tq = em.createQuery(cq);
    tq.setParameter("playerId", pid);
    return tq.getResultList();
}

但是,翻译后的 SQL 可以通过优化 CriteriaQuery 来优化以使用更少的 JOINS。因此,您需要 select 映射的拥有方(Setting)而不是 non-owning 方(Player)。

public List<Setting> getSettingByPlayerId(Long pid){
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Setting> cq = cb.createQuery(Setting.class);
    Root<Setting> settingRoot = cq.from(Setting.class);
    cq.select(settingRoot);
    cq.where(cb.equal(settingRoot.<Player>get("player").<Long>get("id"),cb.parameter((Long.class), "playerId")));   
    TypedQuery<Setting> tq = em.createQuery(cq);
    tq.setParameter("playerId", pid);
    return tq.getResultList();
}