Docs 菜单
Docs 主页
/ /

执行原生数据库查询

在本指南中,您可以学习;了解如何使用MongoDB Extension for Hibernate ORM 在MongoDB 数据库上运行原生查询。原生查询允许您使用MongoDB查询语言 (MQL) 来指定查询,而不是使用 Hibernate Query Language (HQL) 或 Jakarta Persistence Query Language (JPQL)。 MQL是一种查询语法,旨在与 MongoDB 基于文档的模型进行交互。

提示

最出色的特性

要学习;了解有关 MQL 语法和功能的更多信息,请参阅MongoDB Server手册中的 MongoDB查询语言参考。

Hibernate ORM 的 createQuery() 方法不支持某些MongoDB查询功能。 createNativeQuery() 方法允许您在MQL中指定数据库查询并绕过 Hibernate ORM 扩展的某些操作限制。

您还可以直接对 MongoClient对象运行查询,以扩展查询功能。

本指南中的示例使用Movie 实体,它表示Atlas示例数据集中的sample_mflix.movies 集合。Movie 实体具有以下定义:

import com.mongodb.hibernate.annotations.ObjectIdGenerator;
import org.bson.types.ObjectId;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
@Entity
@Table(name = "movies")
public class Movie {
@Id
@ObjectIdGenerator
private ObjectId id;
private String title;
private String plot;
private int year;
private int runtime;
private String[] cast;
public Movie(String title, String plot, int year, int runtime, String[] cast) {
this.title = title;
this.plot = plot;
this.year = year;
this.runtime = runtime;
this.cast = cast;
}
public Movie() {
}
public ObjectId getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPlot() {
return plot;
}
public void setPlot(String plot) {
this.plot = plot;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getRuntime() {
return runtime;
}
public void setRuntime(int runtime) {
this.runtime = runtime;
}
public String[] getCast() {
return cast;
}
public void setCast(String[] cast) {
this.cast = cast;
}
}

要学习;了解如何创建Java应用程序以使用MongoDB Extension for Hibernate ORM 与此MongoDB示例集合交互,请参阅 入门教程。

注意

持久性上下文

启用Hibernate ORM 能够与数据库交互,您必须使用 HibernateSession 或 Jakarta PersistenceEntityManager 在持久性上下文中运行操作。本指南中的示例使用 。要学习;了解有关持久性上下文的更多信息,请参阅Session 事务和会话指南。

要运行原生MongoDB查询,请指定MongoDB查询语言 (MQL)声明,其中包括要查询的集合以及聚合管道中的查询条件。

提示

聚合管道 (Aggregation Pipeline)

要学习;了解有关构建聚合管道和运行聚合操作的更多信息,请参阅MongoDB Server手册中的聚合管道参考。

MQL语句采用以下格式:

String mqlSyntax = """
{
aggregate: "<collection to query>",
pipeline: [
<aggregation pipeline stages>
]
}
""";

重要

$ 项目阶段要求

MQL声明中的聚合管道必须包含$project 阶段。要将查询文档作为实体实例返回,您必须在$project 阶段指定除主键字段之外的每个实体字段。

然后,将MQL声明传递给 createNativeQuery() 方法。您无法运行使用参数值的原生查询。相反,请在MQL声明中指定搜索词。

您可以使用原生查询来执行以下操作:

此示例通过将MQL声明传递给 createNativeQuery() 方法来对 sample_mflix.movies集合运行原生查询。代码指定了以下聚合管道阶段:

  • $match:筛选标题字段值为以下内容的文档: "The Parent Trap"

  • $sort:按匹配文档的 year 字段降序排序

  • $project:返回 Movie 实体中定义的每个文档字段

String nativeQuery = """
{
aggregate: "movies",
pipeline: [
{ $match: { title: { $eq: "The Parent Trap" } } },
{ $sort: { year: -1 } },
{ $project: { title: 1, plot: 1, year: 1, runtime: 1, cast: 1 } }
]
}
""";
var results = session.createNativeQuery(nativeQuery, Movie.class)
.getResultList();
for (Movie movie : results) {
System.out.println("Title: " + movie.getTitle() + ", Year: " + movie.getYear());
}
Title: The Parent Trap, Year: 1998
Title: The Parent Trap, Year: 1961

Hibernate ORM 扩展当前不支持使用算术运算符的 HQL 或 JPQL 语句。但是,您可以在MQL声明中使用 MongoDB 的算术运算符对数据执行算术运算。

提示

算术操作符

要学习;了解有关 Hibernate 和MongoDB算术操作符的更多信息,请参阅以下资源:

以下示例对 sample_mflix.movies集合运行原生查询,以执行以下操作:

  • 指定一个 $match 阶段,以匹配 year 值大于 2000runtime字段存在的文档

  • 指定 $addFields 阶段以添加名为 runtimeHours 的新字段

  • 对于新的 runtimeHours字段,使用 $divide 算术运算操作符将 runtime 值从分钟转换为小时

  • 指定一个 $project 阶段以返回 Movie 实体中定义的每个文档字段,但主键字段除外

  • 打印每个已更新文档的 title

String nativeQuery = """
{
aggregate: "movies",
pipeline: [
{ $match: { year: { $gt: 2000 }, runtime: { $exists: true } } },
{ $addFields: {
runtimeHours: { $divide: [ "$runtime", 60 ] }
}},
{ $project: {
title: 1,
plot: 1,
year: 1,
runtime: 1,
cast: 1
}}
]
}
""";
var results = session.createNativeQuery(nativeQuery, Movie.class)
.getResultList();
for (Movie result : results) {
System.out.println("Added field to movie: " + result.getTitle());
}
Added field to movie: Kate & Leopold
Added field to movie: Crime and Punishment
Added field to movie: Glitter
Added field to movie: The Manson Family
Added field to movie: The Dancer Upstairs
Added field to movie: Fantastic Four
...

您可以运行原生查询来对数据库执行MongoDB Search 查询,这是对数据的细粒度文本搜索。这些查询提供高级搜索功能,例如匹配文本短语、对结果的相关性进行评分以及突出显示匹配项。

重要

您无法在ACID 事务中运行MongoDB Search查询。

要指定搜索查询,请创建涵盖要查询的字段的搜索索引。然后,将聚合管道传递给包含 $search$searchMeta 阶段的 createNativeQuery() 方法。

提示

MongoDB Search

要学习;了解有关MongoDB Search 查询和索引的更多信息,请参阅MongoDB Server手册中的MongoDB Search 概述。

此示例通过将 $search管道阶段传递给 createNativeQuery() 方法来运行搜索查询。该代码执行以下操作:

  • 指定涵盖 plot字段的搜索索引。确保将 <indexName> 占位符替换为您的搜索索引名称。

  • 查询 plot 值包含字符串 "whirlwind romance" 且字符串之间的单词数不超过 3 个的文档

  • 指定一个 $project 阶段以返回 Movie 实体中定义的每个文档字段,但主键字段除外

  • 打印匹配文档的 titleplot

String nativeQuery = """
{
aggregate: "movies",
pipeline: [
{
$search: {
index: "<indexName>",
phrase: {
path: "plot",
query: "whirlwind romance",
slop: 3
}
}
},
{
$project: {
title: 1,
plot: 1,
year: 1,
runtime: 1,
cast: 1
}
}
]
}
""";
var results = session.createNativeQuery(nativeQuery, Movie.class)
.getResultList();
for (Movie result : results) {
System.out.println("Title: " + result.getTitle() + ", Plot: " + result.getPlot());
}
Title: Tokyo Fiancèe, Plot: A young Japanophile Belgian woman in Tokyo falls into a whirlwind romance with a Francophile Japanese student.
Title: Designing Woman, Plot: A sportswriter and a fashion-designer marry after a whirlwind romance, and discover they have little in common.
Title: Vivacious Lady, Plot: On a quick trip to the city, young university professor Peter Morgan falls in love with nightclub performer Francey Brent and marries her after a whirlwind romance. But when he goes back ...
Title: Ek Hasina Thi, Plot: A woman falls for a charming and mysterious businessman. The whirlwind romance turns sour when she is framed for his underworld crimes. Now, finally out of prison she is ready for sweet revenge.
Title: Kick, Plot: An adrenaline junkie walks away from a whirlwind romance and embraces a new life as a thief, though he soon finds himself pursued by veteran police officer and engaged in a turf war with a local gangster.
Title: A Tale of Winter, Plot: Felicie and Charles have a serious if whirlwind holiday romance. Due to a mix-up on addresses they lose contact, and five years later at Christmas-time Felicie is living with her mother in ...

如果要运行createQuery() 方法和 createNativeQuery() 方法都不支持的数据库操作,可以直接在Java应用程序中操作 MongoClient对象。使用 MongoClient 时,您可以访问权限MongoDB Java同步驱动程序的功能。

提示

功能支持

要学习;了解必须使用 对象才能访问权限的不支持的MongoDB功能的更多信息,请参阅MongoClient Hibernate ORM 功能兼容性页面。

要学习;了解如何使用Java驾驶员与MongoDB交互,请参阅MongoDB Java驱动程序文档。

您无法使用 Hibernate ORM 扩展在集合上创建索引,但可以实例化 MongoClient 并使用Java驱动程序的 createIndex() 方法。以下代码在 sample_mflix.movies集合上创建 title字段索引:

// Replace the <connection URI> placeholder with your MongoDB connection URI
String uri = "<connection URI>";
MongoClient mongoClient = MongoClients.create(uri);
MongoDatabase db = mongoClient.getDatabase("sample_mflix");
MongoCollection<Document> collection = db.getCollection("movies");
String indexResult = collection.createIndex(Indexes.ascending("title"));
System.out.println(String.format("Index created: %s", indexResult));
Index created: title_1

要学习;了解有关如何使用Java驾驶员创建索引的更多信息,请参阅Java驾驶员文档中的索引指南。

要进一步学习;了解本指南中讨论的查询语言,请参阅以下资源:

后退

指定查询

在此页面上