1. Overview
1.概述
In the previous article in this series, we showed how to persist Java objects to different data stores. For more details, please check Guide to Java Data Objects.
在本系列的上一篇文章中,我们展示了如何将Java对象持久化到不同的数据存储中。更多细节,请查看Java数据对象指南。
JDO supports different query languages to provide flexibility for the developer to use the query language he is most acquainted with.
JDO支持不同的查询语言,以提供灵活性,让开发者使用他最熟悉的查询语言。
2. JDO Query Languages
2.JDO查询语言
JDO supports the following query languages:
JDO支持以下查询语言。
- JDOQL – a query language using Java syntax
- Typed JDOQL – following JDOQL syntax but providing an API to ease using the queries.
- SQL – used only for RDBMS.
- JPQL – provided by Datanucleus, but not part of the JDO specifications.
3. Query API
3.API查询
3.1. Creating a Query
3.1.创建一个查询
To create a query, we need to specify the language as well as a query String:
要创建一个查询,我们需要指定语言以及一个查询String:。
Query query = pm.newQuery(
"javax.jdo.query.SQL",
"select * from product_item where price < 10");
If we do not specify the language, it defaults to the JDOQL:
如果我们不指定语言,它默认为JDOQL。
Query query = pm.newQuery(
"SELECT FROM com.baeldung.jdo.query.ProductItem WHERE price < 10");
3.2. Creating a Named Query
3.2.创建一个命名查询
We can also define the query and refer to it by its saved name.
我们也可以定义查询,并通过其保存的名称来引用它。
To do so, we first create a ProductItem class:
为此,我们首先创建一个ProductItem类。
@PersistenceCapable
public class ProductItem {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.INCREMENT)
int id;
String name;
String status;
String description;
double price;
//standard getters, setters & constructors
}
Next, we add a class configuration to the META-INF/package.jdo file to define a query and name it:
接下来,我们在META-INF/package.jdo文件中添加一个类配置,以定义一个查询并为其命名。
<jdo>
<package name="com.baeldung.jdo.query">
<class name="ProductItem" detachable="true" table="product_item">
<query name="PriceBelow10" language="javax.jdo.query.SQL">
<![CDATA[SELECT * FROM PRODUCT_ITEM WHERE PRICE < 10]]>
</query>
</class>
</package>
</jdo>
We defined a query named “PriceBelow10″.
我们定义了一个名为”PriceBelow10″的查询。
We can use it in our code:
我们可以在我们的代码中使用它。
Query<ProductItem> query = pm.newNamedQuery(
ProductItem.class, "PriceBelow10");
List<ProductItem> items = query.executeList();
3.3. Closing a Query
3.3.关闭一个查询
To save resources, we can close queries:
为了节省资源,我们可以关闭查询。
query.close();
Equivalently, we can close a specific result set by passing it as a parameter to the close() method:
同样地,我们可以通过将特定的结果集作为参数传递给close()方法来关闭它。
query.close(ResultSet);
3.4. Compiling a Query
3.4.编译一个查询
If we want to validate a query, we can call the compile() method:
如果我们想验证一个查询,我们可以调用compile()方法。
query.compile();
If the query is not valid, then the method will throw a JDOException.
如果查询无效,那么该方法将抛出一个JDOException.。
4. JDOQL
4.JDOQL
JDOQL is an object-based query language, designed to provide the power of SQL language and preserve the Java object relationships in the application model.
JDOQL是一种基于对象的查询语言,旨在提供SQL语言的力量,并保留应用程序模型中的Java对象关系。
JDOQL queries can be defined in a single-String form.
JDOQL查询可以以single-String形式定义。
Before we dive deeper, let’s go over some basic concepts:
在我们深入研究之前,让我们先看看一些基本概念。
4.1. Candidate Class
4.1.候选类别
The candidate class in the JDOQL has to be a persistable class. We’re using the full class name instead of the table name in the SQL language:
JDOQL中的候选类必须是一个可持续的类。我们在SQL语言中使用全类的名字而不是表的名字。
Query query = pm.newQuery("SELECT FROM com.baeldung.jdo.query.ProductItem");
List<ProductItem> r = query.executeList();
As we can see in the example above, the com.baeldung.jdo.query.ProductItem is the candidate class here.
在上面的例子中我们可以看到,com.baeldung.jdo.query.ProductItem是这里的候选类。
4.2. Filter
4.2.过滤器
A filter can be written in Java but must evaluate to a boolean value:
一个过滤器可以用Java编写,但必须评估为一个布尔值。
Query query = pm.newQuery("SELECT FROM com.baeldung.jdo.query.ProductItem");
query.setFilter("status == 'SoldOut'");
List<ProductItem> result = query.executeList();
4.3. Methods
4.3.方法
JDOQL does not support all Java methods, but it supports various methods that we can call them from the query and can be used in a wide range:
JDOQL并不支持所有的Java方法,但它支持各种方法,我们可以从查询中调用它们,并且可以在很大范围内使用。
query.setFilter("this.name.startsWith('supported')");
For more details about the supported methods, please check this link.
关于支持的方法的更多细节,请查看此链接。
4.4. Parameters
4.4.参数[/strong]
We can pass values to queries as parameters. We can either define the parameters explicitly or implicitly.
我们可以把值作为参数传递给查询。我们可以明确地或隐含地定义参数。
To define a parameter explicitly:
要明确地定义一个参数。
Query query = pm.newQuery(
"SELECT FROM com.baeldung.jdo.query.ProductItem "
+ "WHERE price < threshold PARAMETERS double threshold");
List<ProductItem> result = (List<ProductItem>) query.execute(10);
This can also be achieved using the setParameters method:
这也可以通过setParameters方法实现。
Query query = pm.newQuery(
"SELECT FROM com.baeldung.jdo.query.ProductItem "
+ "WHERE price < :threshold");
query.setParameters("double threshold");
List<ProductItem> result = (List<ProductItem>) query.execute(10);
We can do it implicitly by not defining a parameter type:
我们可以通过不定义参数类型来隐含地做到这一点。
Query query = pm.newQuery(
"SELECT FROM com.baeldung.jdo.query.ProductItem "
+ "WHERE price < :threshold");
List<ProductItem> result = (List<ProductItem>) query.execute(10);
5. JDOQL Typed
5.JDOQL的类型化
To use JDOQLTypedQueryAPI, we need to prepare the environment.
为了使用JDOQLTypedQueryAPI,我们需要准备环境。
5.1. Maven Setup
5.1.Maven设置
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-jdo-query</artifactId>
<version>5.0.2</version>
</dependency>
...
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
The latest versions of these dependencies are datanucleus-jdo-query and maven-compiler-plugin.
这些依赖的最新版本是datanucleus-jdo-query和maven-compiler-plugin。
5.2. Enabling Annotation Processing
5.2.启用注释处理
For Eclipse, we can follow the steps below to enable annotated processing:
对于Eclipse,我们可以按照下面的步骤来启用注释处理。
- Go to Java Compiler and make sure the compiler compliance level is 1.8 or above
- Go to Java Compiler → Annotation Processing and enable the project specific settings and enable annotation processing
- Go to Java Compiler → Annotation Processing → Factory Path, enable the project specific settings and then add the following jars to the list: javax.jdo.jar, datanucleus-jdo-query.jar
The above preparation means that whenever we compile persistable classes, the annotation processor in the datanucleus-jdo-query.jar will generate a query class for each class annotated by @PersistenceCapable.
上述准备工作意味着,每当我们编译可持久化类时,datanucleus-jdo-query.jar中的注释处理器将为每个被@PersistenceCapable.注释的类生成一个查询类。
In our case, the processor generates a QProductItem class. The generated class has almost the same name of the persistable class, albeit prefixed with a Q.
在我们的案例中,处理器生成了一个QProductItem类。生成的类的名字几乎与可持久化的类相同,尽管前缀是Q。
5.3. Create JDOQL Typed Query:
5.3.创建JDOQL类型的查询:
JDOQLTypedQuery<ProductItem> tq = pm.newJDOQLTypedQuery(ProductItem.class);
QProductItem cand = QProductItem.candidate();
tq = tq.filter(cand.price.lt(10).and(cand.name.startsWith("pro")));
List<ProductItem> results = tq.executeList();
We can make use of the query class to access the candidate fields and use its available Java methods.
我们可以利用查询类来访问候选字段并使用其可用的Java方法。
6. SQL
6.SQL
JDO supports the SQL language in case we are using an RDBMS.
在我们使用RDBMS的情况下,JDO支持SQL语言。
Let’s create SQL query:
让我们来创建SQL查询。
Query query = pm.newQuery("javax.jdo.query.SQL","select * from "
+ "product_item where price < ? and status = ?");
query.setClass(ProductItem.class);
query.setParameters(10,"InStock");
List<ProductItem> results = query.executeList();
We used the setClass() for the query to retrieve ProductItem objects when we execute the query. Otherwise, it retrieves an Object type.
当我们执行查询时,我们使用查询的setClass() 来检索ProductItem对象。否则,它就会检索到一个Object类型。
7. JPQL
7.JPQL
JDO DataNucleus provides the JPQL language.
JDO DataNucleus提供了JPQL语言。
Let’s Create a query using JPQL:
让我们使用JPQL创建一个查询。
Query query = pm.newQuery("JPQL","select i from "
+ "com.baeldung.jdo.query.ProductItem i where i.price < 10"
+ " and i.status = 'InStock'");
List<ProductItem> results = (List<ProductItem>) query.execute();
The entity name here is com.baeldung.jdo.query.ProductItem. We cannot use the class name only. This is because JDO doesn’t have metadata to define an entity name like JPA. We have defined a ProductItem p, and after that, we can use p as an alias to refer to the ProductItem.
这里的实体名称是com.baeldung.jdo.query.ProductItem。我们不能只使用类的名字。这是因为JDO没有像JPA那样的元数据来定义实体名称。我们已经定义了一个ProductItem p,之后,我们可以用p作为别名来引用ProductItem.。
For more details about JPQL syntax, please check this link.
关于JPQL语法的更多细节,请查看这个链接。
8. Conclusion
8.结论
In this article, we showed the different query languages that are supported by JDO. We showed how to save named queries for reusing and explained the JDOQL concepts and showed how to use SQL and JPQL with JDO.
在这篇文章中,我们展示了JDO所支持的不同查询语言。我们展示了如何保存命名的查询以便重复使用,并解释了JDOQL的概念,展示了如何在JDO中使用SQL和JPQL。
The code examples in the article can be found over on GitHub.
文章中的代码示例可以在GitHub上找到over。