2

有谁知道如何使用按位 AND (&) 作为 JPA NamedQuery 的条件而不必使用 @NamedNativeQuery?

我将状态位存储在一个字段中。

我将以下定义用于视图实体:

@NamedQueries({
    @NamedQuery(name="ViewProductsList.findAll", query="SELECT v FROM ViewProductsList v"),
    @NamedQuery(name="ViewProductsList.findFeatured", query="SELECT v FROM ViewProductsList v WHERE v.statusId & 16"),
    @NamedQuery(name="ViewProductsList.findBySubcategory", query="SELECT v ViewProductsList v WHERE v.subcatId IN (:subcatIds)"),
})

第一个工作正常,但第二个不喜欢这个表达式,我得到以下信息:

18:02:13,528 DEBUG [DataNucleus.Query] - JPQL Single-String with "SELECT v FROM ViewProductsList v WHERE v.statusId & 16"
18:02:13,553 DEBUG [DataNucleus.Query] - JPQL Query : Compiling "SELECT v FROM ViewProductsList v WHERE v.statusId & 16"
>>ERROR: 'Portion of expression could not be parsed: & 16'

在生产中使用 dev MySQL 数据库和 Google Cloud SQL,所以它必须在这两个版本上工作......

有任何想法吗?

更新的问题:

当使用如下定义的@NamedNativeQuery 时:

@NamedNativeQuery(name = "ViewProductsList.findFeatured", query = "SELECT * FROM view_products_list v")

并将其称为如下:

Query query=em.createNativeQuery("ViewProductsList.findFeatured", ViewProductsList.class);
List<ViewProductsList> list = query.getResultList();

我收到以下错误:

java.lang.IllegalStateException: You cannot invoke getResultList/getSingleResult when the Query is an UPDATE/DELETE
    at org.datanucleus.api.jpa.JPAQuery.getResultList(JPAQuery.java:161)
    at cultivartehidroponia.ProductsServlet.doGet(ProductsServlet.java:81) ...

我尝试了许多 createNativeQuery 示例的变体,但均未成功。有人知道使用 datanucleus 的本地查询示例吗?

同样,使用带有 createNamedQuery 的普通 @NamedQuery 可以正常工作!

提前致谢!!!

4

3 回答 3

9

Bitwise AND不是 JPQL 的一部分。但...

可以使用2条规则:

  1. 除以 2^х 会将位右移 x(例如 1011010/1000=1011)
  2. z mod 2 = 1 如果右位为 1(例如 1011 mod 2 = 1)

尝试

SELECT v FROM ViewProductsList v WHERE MOD(v.statusId/16 , 2) = 1
于 2014-02-04T09:07:48.277 回答
2

“按位与”不是JPQL 的一部分。本机查询是可移植的方式。

于 2014-01-21T07:50:47.577 回答
0

答案很晚,但仍然是一个……您可以在 SQL 端声明一个执行按位操作(移位和屏蔽)的函数。例如(PostgreSQL):

CREATE OR REPLACE FUNCTION extractBits(bitmap bigint, bitOffset integer, bitMask bigint) RETURNS bigint
    LANGUAGE plpgsql IMMUTABLE
    AS $$
BEGIN
    return (bitmap >> bitOffset) & bitMask;
END;$$ RETURNS NULL ON NULL INPUT;

然后,如果/当使用 JPA 标准构建器时,您可以使用以下内容:

Expression<Long> bitmap = ...; // Path or expression to raw bitmap

Expression<Long> extracted = 
    builder.function("extractBits", Long.class, bitmap, shiftCount, bitMask);

Predicate predicate = builder.equal(extracted, desiredValue);

如果您希望在 JPQL 中使用,它会有所不同,但这里有关于如何操作的答案。例如:

从 JPA 调用 oracle 函数

那个有 EclipseLink 链接的答案:http: //www.eclipse.org/eclipselink/documentation/2.5/jpa/extensions/j_func.htm

使用休眠: https ://thorben-janssen.com/database-functions/

于 2021-08-27T14:28:13.423 回答