想知道如何看待mysql json专栏?
product table:
...
category_ids json null,
...
category_ids例如) [19, 102, 108]
如果我想搜索包含类别id 102的产品列表,如何使用queryDSL进行查询?
我尝试了JsonNode类型,但它不起作用。
根据这些标记,我假设您使用查询
列表创建 JPQL(或Hibernate HQL)查询。这一点很重要,因为为了让JSON类型与查询一起使用,它们不仅必须使用查询和MySQL,而且最重要的是使用查询语言本身,在这种情况下来自Hibernate。
我假设您已经成功地将json
列正确地映射到JacksonsJsonNode
类型。如果没有,那么重要的是要注意,对于任何非标准类型,都需要在Hibernate中注册自定义类型。您可以制作自己的自定义类型,也可以使用现有的实现。我强烈推荐Vlad开发的hibernate-type
库(包括我自己在内的一些人的贡献)。如何将hibernate-type
集成到您的项目中,在他对Stackoverflow问题的回答中得到了很好的解释:https://stackoverflow.com/a/37946530/2104280
您需要做的第一件事是在项目pom中设置以下Hibernate Types Maven依赖项。xml
配置文件:
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>${hibernate-types.version}</version>
</dependency>
现在,您需要在类级别或package-info.java包级别描述符中声明JsonType
,如下所示:
@TypeDef(name = "json", typeClass = JsonType.class)
并且,实体映射将如下所示:
@Type(type = "json")
@Column(columnDefinition = "jsonb")
private Location location;
现在,您将能够在查询中的简单操作中使用 JSON 属性。允许的操作基本上包括基本比较(=
、!=
和 IS(非)空)
。其他操作不可用,因为这些操作仅在 MySQL 中定义,而不是在 JPQL 或 HQL 查询语言中定义。
您要检查 JSON 数组是否包含特定元素。我假设category_ids
表示一个 JSON 数组。那么这意味着你想要生成的MySQL代码段很可能是category_ids? :类别Id
。
我想指出的是,这仅适用于存储为字符串的ID,而不是JSON数组中的数字。您可能希望将category_ids
映射为双关语[]
。与 JSON 类型一样,Hibernate类型库也支持数组类型
,因此答案对于数组的工作方式相同。
但是,JSON_CONTAINS(category_ids,:categoryId)
不是有效的HQL/JPQL,因为该查询语言中不存在该函数。如果我们想在HQL/JPQL中呈现JSON_CONTAINS(category_ids,:categoryId)
,我们需要定义一个自定义函数,将JSON_CCONTAINS。
有两种方法可以在Hibernate中声明自定义函数。
扩展您正在使用的方言,并在那里声明函数。https://stackoverflow.com/a/42486291/2104280 中很好地描述了这种方法。
- 使用
元数据生成器初始化程序
SPI 在引导期间注册自定义函数。https://stackoverflow.com/a/41369853/2104280 中介绍了此方法。
使用< code > MetadataBuilderInitializer
方法,代码将如下所示:
public class JSONMetadataBuilderInitializer
implements MetadataBuilderInitializer {
@Override
public void contribute(MetadataBuilder metadataBuilder,
StandardServiceRegistry serviceRegistry) {
metadataBuilder.applySqlFunction("json_contains_key",
new SQLFunctionTemplate(BooleanType.INSTANCE,
"JSON_CONTAINS(?1, ?2, '$'"));
}
}
最后,您最终会为您的JsonNode
属性获得一个Hibernate类型,以及一个用于检查是否存在密钥的自定义函数。密钥可以在JPQL/HQL中如下使用:
SELECT product FROM Product product WHERE json_contains_key(product.categories, '1234') = true;
这将产生以下 SQL:
SELECT * FROM product WHERE JSON_CONTAINS(categories, '1234', '$') = true;
然而,您希望通过Querydsl构建这个JPQL/HQL查询,这意味着还需要几个步骤。我们需要为创建的函数构造新的表达式类型。基本上有两种选择:
运算符
实现,并在扩展的 JPQL 模板
中为该运算符
注册一个模板
。一个模板表达式
(字面意思是 JPQL 的片段)。第二种方法更简单,所以我将在这里使用。使用TemplateExpression
,Querydsl中的以下代码将生成上述JPQL查询:
queryFactory.select(QProduct.product)
.from(QProduct.product)
.where(Expressions.booleanTemplate(
"json_contains_key({0}, {1})",
QProduct.product.categories,
Expressions.constants("1234").isTrue())
.fetch();
然而,这并不像您在Querydsl中习惯的那样流畅。可以使用自定义表达式类型扩展Querydsl,并在此假设引入JsonExpression。还可以扩展querydsl apt
,以便在静态元模型(Q-classes)中自动生成此表达式类型的路径。我专门为此构建了扩展库hibernate types querydsl apt
。它为Hibernate types项目中的自定义类型添加了各种自定义表达式类型(例如范围、数组、json、hstore、间隔)。它还自动注册主操作的自定义函数。使用我的扩展,数组的用例将非常简单:
@Entity
@TypeDefs({
@TypeDef(name = "int-array", typeClass = IntArrayType.class, defaultForType = int[].class)
})
public class ArrayEntity {
@Id
Long id;
@Type(type = "int-array")
@Column(name = "sensor_values", columnDefinition = "integer[]")
int[] sensorValues;
}
List<Tuple> fetch = new JPAQuery<>(entityManager, ExtendedHQLTemplates.DEFAULT)
.from(arrayEntity)
.select(arrayEntity)
.where(arrayEntity.sensorValues.contains(123))
.fetch();
更多示例请访问:https://github.com/jwgmeligmeyling/hibernate-types-querydsl-apt/blob/master/querydsl-ext-testsuite/src/test/java/com/pallasathenagroup/querydsl/ArrayEntityPathTest.java .
样本子句 sample_clause允许您指示数据库从表中的随机数据样本中进行选择,而不是从整个表中进行选择。 我想使用QueryDSL运行下面的查询 样本子句 sample_clause允许您指示数据库从表中的随机数据样本中进行选择,而不是从整个表中进行选择。 从测试t样本(80)中选择,其中t.test_id=01,t.test _ suite _ id = 02 其中条件是动态的,我使用qu
问题内容: 我有以下查询: 查询在具有25.000行的数据库表上执行。该查询的执行时间约为40秒。结果将显示在网页上,因此等待40秒以获取结果并不是很好。 有没有一种方法可以执行此查询并保存其输出?因为如果每天晚上执行此查询就足够了。 最好的方法是什么?我应该创建一个cronjob并执行此查询并将结果写入数据库吗?或者,还有更好的方法? 或者我可以优化此查询以使其更快? 问题答案: 我认为所有这些
需要实现sql查询,如: 如何使用QueryDSL编写这样的语句?(我没有使用任何JPA)。任何帮助/提示都非常感谢!
主要内容:匹配所有查询,全文查询,匹配查询,multi_match查询,查询字符串查询,期限等级查询,范围查询,复合查询,连接查询,地理查询在Elasticsearch中,通过使用基于JSON的查询进行搜索。 查询由两个子句组成 - 叶查询子句 - 这些子句是匹配,项或范围的,它们在特定字段中查找特定值。 复合查询子句 - 这些查询是叶查询子句和其他复合查询的组合,用于提取所需的信息。 Elasticsearch支持大量查询。 查询从查询关键字开始,然后以对象的形式在其中包含条件和过滤器。以下描
问题内容: 我是事件/回调样式编程和NodeJS的新手。我正在尝试实现一个小的http服务器,它使用node-mysql模块来提供ddbb数据。 我的问题来自查询结构。由于经常有一些查询需要运行先前查询的结果,因此我无法同时(异步)运行所有查询,因此不得不等待一些结果。 我的第一种方法是同时运行所有非依赖性查询,然后循环运行,直到所有非依赖性查询都设置了一个标志,说我已经完成,这样我就可以继续处理