标准 Jpa Select 外国实体
Criteria Jpa Select foreign entity
任何人都可以帮助将此 hsql 转换为条件,请:
Select S From Player P Inner Join P.setting S Where P.id = :pid
我在处理这个查询时感到困惑。
即使你在做一个 JOIN,从你的变量名来看,我觉得你在 Player
和 Setting
之间建立了一个 @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();
}
任何人都可以帮助将此 hsql 转换为条件,请:
Select S From Player P Inner Join P.setting S Where P.id = :pid
我在处理这个查询时感到困惑。
即使你在做一个 JOIN,从你的变量名来看,我觉得你在 Player
和 Setting
之间建立了一个 @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();
}