任何人都可以帮助将此hsql转换为条件,请:
Select S From Player P Inner Join P.setting S Where P.id = :pid
我对此查询感到困惑。
答案 0 :(得分:0)
即使您正在进行加入,从您的变量名称看起来就像您在@OneToOne
和Player
之间建立Setting
关系一样,是吗?
如果您建模@OneToOne
关系,Setting
加载Player
时将会加载EAGER。这意味着您可以执行简单的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();
}
如果您建模@OneToMany
从Player
到Setting
的关系,则可以执行JOIN,因为该映射已加载LAZY。在您使用条件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();
}
但是,通过优化CriteriaQuery,可以优化已翻译的SQL以使用更少的JOINS。因此,您需要选择映射的拥有方(Setting
)而不是非拥有方(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();
}