Hibernate Criteria API 仅使用 id 连接到另一个 table
Hibernate Criteria API join to another table only with id
我正在尝试使用 Hibernate Criteria API 从一个 table 连接到另一个。问题是 table Contract 只有 salesId 被定义为 long(所以没有 FK)。然后我不确定如何将合同与销售联系起来。最好在下面的示例中进行解释。
架构如下:
Table Contract:
----------------------
ID | salesId |
----------------------
1 | 1 |
2 | 2 |
----------------------
Table Sales:
----------------------
ID | code |
----------------------
1 | SALES_1 |
2 | SALES_2 |
----------------------
在合同实体中我只有 private Long salesId;
而我需要实现的是这样的:
getSession().createCriteria(Contract.class)
.createAlias("salesId", "s") // somehow connect to Sales table
.add(Restrictions.eq("s.code", salesCode)); // salesCode is param
所以不能直接用createAlias↓,因为不知道hibernate
.createAlias("sales", "s")
我无法更改模型以在 table 之间创建 FK。有没有办法解决这个问题?我想避免 SQL 字符串连接。
编辑: 我使用 Hibernate Criteria API 的原因是其他查询参数(此处未显示)是可选的,因此它们不能成为一部分SQL 查询。所以这就是我不能使用 HQL 的原因。
你为什么不想使用 HQL 并编写这样的查询:
select * from Contact t1 join Sales t2 where t1.salesId=t2.ID
这可能是您在休眠 5 中的解决方案:
Criteria criteria = getSession().createCriteria(Contract.class);
Criterion subquery = Restrictions.sqlRestriction("{alias}.salesId = (select id from TABLE_SALES where code = ?)", salesCode, StandardBasicTypes.STRING);
criteria.add(subquery);
您想将它用于动态查询,然后您可以根据您的业务逻辑在自定义限制上使用该标准。
criteria.add(Restrictions.and(subquery)) -- example
criteria.add(Restrictions.or(subquery)) -- example
PD:TABLE_SALES 必须是您在数据库中的销售 table 名称,您也可以 pre-append 它的架构。
干杯。
它不是 SQL“连接”,但您可以组合 DetachedCriteria and Projection 创建外部 SQL“在”(或“不在”):
criteria.add(Restrictions.eq("table1ColumnName", XXX));
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(OtherMappedClass.class);
detachedCriteria.setProjection(Property.forName("sameColumnName"));
detachedCriteria.add(Restrictions.eq("table2ColumnName", XXX)););
criteria.add(Property.forName("sameColumnName").in(detachedCriteria));
您可以使用多个 Root 对象来解决它。例如
var rootContract = criteriaQuery.from(Contract.class);
var rootSales = criteriaQuery.from(Sales.class);
然后定义以下谓词:
predicates.add(criteriaBuilder.equal(rootContract.get("salesId"), rootSales.get("id")));
predicates.add(criteriaBuilder.equal(rootSales.get("code"), "SALES_1"));
我正在尝试使用 Hibernate Criteria API 从一个 table 连接到另一个。问题是 table Contract 只有 salesId 被定义为 long(所以没有 FK)。然后我不确定如何将合同与销售联系起来。最好在下面的示例中进行解释。
架构如下:
Table Contract:
----------------------
ID | salesId |
----------------------
1 | 1 |
2 | 2 |
----------------------
Table Sales:
----------------------
ID | code |
----------------------
1 | SALES_1 |
2 | SALES_2 |
----------------------
在合同实体中我只有 private Long salesId;
而我需要实现的是这样的:
getSession().createCriteria(Contract.class)
.createAlias("salesId", "s") // somehow connect to Sales table
.add(Restrictions.eq("s.code", salesCode)); // salesCode is param
所以不能直接用createAlias↓,因为不知道hibernate
.createAlias("sales", "s")
我无法更改模型以在 table 之间创建 FK。有没有办法解决这个问题?我想避免 SQL 字符串连接。
编辑: 我使用 Hibernate Criteria API 的原因是其他查询参数(此处未显示)是可选的,因此它们不能成为一部分SQL 查询。所以这就是我不能使用 HQL 的原因。
你为什么不想使用 HQL 并编写这样的查询:
select * from Contact t1 join Sales t2 where t1.salesId=t2.ID
这可能是您在休眠 5 中的解决方案:
Criteria criteria = getSession().createCriteria(Contract.class);
Criterion subquery = Restrictions.sqlRestriction("{alias}.salesId = (select id from TABLE_SALES where code = ?)", salesCode, StandardBasicTypes.STRING);
criteria.add(subquery);
您想将它用于动态查询,然后您可以根据您的业务逻辑在自定义限制上使用该标准。
criteria.add(Restrictions.and(subquery)) -- example
criteria.add(Restrictions.or(subquery)) -- example
PD:TABLE_SALES 必须是您在数据库中的销售 table 名称,您也可以 pre-append 它的架构。
干杯。
它不是 SQL“连接”,但您可以组合 DetachedCriteria and Projection 创建外部 SQL“在”(或“不在”):
criteria.add(Restrictions.eq("table1ColumnName", XXX));
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(OtherMappedClass.class);
detachedCriteria.setProjection(Property.forName("sameColumnName"));
detachedCriteria.add(Restrictions.eq("table2ColumnName", XXX)););
criteria.add(Property.forName("sameColumnName").in(detachedCriteria));
您可以使用多个 Root 对象来解决它。例如
var rootContract = criteriaQuery.from(Contract.class);
var rootSales = criteriaQuery.from(Sales.class);
然后定义以下谓词:
predicates.add(criteriaBuilder.equal(rootContract.get("salesId"), rootSales.get("id")));
predicates.add(criteriaBuilder.equal(rootSales.get("code"), "SALES_1"));