标准Jpa选择外国实体

时间:2015-11-27 06:52:08

标签: sql jpa inner-join hsqldb

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

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

我对此查询感到困惑。

1 个答案:

答案 0 :(得分:0)

即使您正在进行加入,从您的变量名称看起来就像您在@OneToOnePlayer之间建立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();        
}

如果您建模@OneToManyPlayerSetting 的关系,则可以执行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();
}