java - 使用 HQL 通过多个映射表进行选择?
问题描述
我很难Brand
从给定Country
的 HQL 中选择一个。我做了一些逆向工程,所以你可以想象我的数据库是如何建模的:
Brand
要从右边选择,Country
我必须经历Address
他们的City
and State
。
在带注释的映射方面,我已经这样做了:
牌
@Table(name = "brand")
public class Brand extends BasicModel {
private String name;
@OneToMany(targetEntity = Address.class, cascade = CascadeType.ALL,
fetch = FetchType.LAZY, orphanRemoval = true)
@JoinTable(name="brand_address",
joinColumns = { @JoinColumn(name = "brand_id") },
inverseJoinColumns = { @JoinColumn(name = "address_id") })
private Set<Address> address;
地址
@Table(name = "address")
public class Address extends BasicModel {
@NotNull
@ManyToOne
private AddressCity city;
AddressCity
被映射到AddressState
哪个被映射到AddressCountry
的方式与AddressCity
上面的映射相同Address
。
该表brand_address
是由 Hibernate 自动创建的。
现在使用 SQL,我需要加入所有这些表才能到达,Country
但由于它已使用 Hibernate 注释映射,我应该如何编写 HQL 以Brand
从给定的中选择Country
?
信息:当我创建一个包含一组地址的国家/地区时,该表brand_address
已正确填充。
到目前为止起作用的只是选择,Brand
而 Hibernate 将返回所有填充的对象。我可以通过以下方式做到这一点:
Query query = session
.createQuery("from Brand brand " +
"where brand.name = :brandName " +
"and brand.deleted is null");
query.setParameter("brandName", brandName);
有了这个,我可以很容易地过滤掉Brands
那个名字但从 other 中过滤掉Countries
,但它闻起来不像是最佳实践......
当我尝试时,到目前为止还没有奏效:
Query query = session
.createQuery("from Brand brand " +
"where brand.name = :brandName " +
"and Address.city.state.country.code = :countryCode " +
"and brand.deleted is null");
query.setParameter("brandName", brandName);
query.setParameter("countryCode", countryCode);
和
Query query = session
.createQuery("from Brand brand " +
"where brand.name = :brandName " +
"and AddressCountry.code = :countryCode " +
"and brand.deleted is null");
query.setParameter("brandName", brandName);
query.setParameter("countryCode", countryCode);
我该如何解决?有没有办法让我country
在上面的查询中不写多个连接?我是否应该使用它已经工作的方式全部选择它并将结果过滤回我的 DAO 中?
我一直在互联网上搜索此信息,但只找到了有关如何映射和插入信息的信息,而不是真正有关如何编写将通过表进行选择的查询的信息。
我提前感谢你们美丽的人可以通过我的方式发送的任何帮助和建议!
更新 1:我尝试添加
left join brand.address as a
with a.city.state.country.code = :countryCode
它导致了一个新的错误:
java.sql.SQLSyntaxErrorException:“on 子句”中的未知列“addresscit3_.state_id”
使用以下日志:
14:02:43.646 [main] DEBUG org.hibernate.hql.internal.ast.util.JoinProcessor - Using FROM fragment [brand brand0_]
14:02:43.646 [main] DEBUG org.hibernate.hql.internal.ast.util.JoinProcessor - Using FROM fragment [inner join address_state addresssta4_ on addresscit3_.state_id=addresssta4_.id]
14:02:43.646 [main] DEBUG org.hibernate.hql.internal.ast.util.JoinProcessor - Using FROM fragment [inner join address_country addresscou5_ on addresssta4_.country_id=addresscou5_.id]
14:02:43.647 [main] DEBUG org.hibernate.hql.internal.ast.util.JoinProcessor - Using FROM fragment [inner join brand_address addresses1_ on brand0_.id=addresses1_.brand_id inner join address address2_ on addresses1_.address_id=address2_.id and (addresscou5_.code=?)]
14:02:43.647 [main] DEBUG org.hibernate.hql.internal.ast.util.JoinProcessor - Using FROM fragment [inner join address_city addresscit3_ on address2_.city_id=addresscit3_.id]
14:02:43.647 [main] DEBUG org.hibernate.hql.internal.antlr.HqlSqlBaseWalker - select >> end [level=1, statement=select]
更新 2:解决方案
使用with
@guillaume 建议的密钥确实改变了错误,使得连接顺序似乎放错了位置......我的一个朋友建议使用join fetch
因为延迟加载,我调整了查询,直到一切都到位,如下所示:
.createQuery("from Brand brand " +
"join fetch brand.addresses as a " +
"where brand.name = :brandName " +
"and a.city.state.country.code = :countryCode " +
"and brand.deleted is null");
解决方案
该条件Address.city.state.country.code = :countryCode
没有意义,因为 Address 实际上是一个Set
地址(将其命名为地址可能会更清楚)。
试试这个:
from Brand brand
left join brand.address as a
with a.city.state.country.code = :countryCode
推荐阅读
- vba - 计算 Excel 附件的数量
- python - 如何在 Python 和 Pandas 的 pos_tag 中使用 lambda
- python - 如何从索引列表中选择 QtableWidget 中的单元格
- html - HTML 中两个 UL 之间的控制空间
- regex - mongo:使用正则表达式进行文本搜索
- sql - 在 Access SQL 中标准化名字和姓氏
- python - 如何绘制从旋转坐标派生的地理坐标的角点
- reinforcement-learning - 有没有办法在winx32架构上安装cntk?
- python - 从今天的日期中减去 pandas Dataframe 值
- arrays - NSUserDefaults 检查键的值是否存在