Введение в JDO Queries 2/2

Введение в JDO Queries 2/2

1. обзор

В предыдущей статье этой серии мы показали, как сохранить объекты Java в разных хранилищах данных. Для получения дополнительных сведений проверьтеGuide to Java Data Objects.

JDO поддерживает различные языки запросов, чтобы предоставить разработчику возможность использовать язык запросов, с которым он наиболее знаком.

2. Языки запросов JDO

JDO поддерживает следующие языки запросов:

  • JDOQL - язык запросов, использующий синтаксис Java

  • Типизированный JDOQL - следуя синтаксису JDOQL, но предоставляя API для упрощения использования запросов.

  • SQL - используется только для СУБД.

  • JPQL - предоставляется Datanucleus, но не является частью спецификаций JDO.

3. API запросов

3.1. Создание запроса

Чтобы создать запрос, нам нужно указать язык, а также запросString:

Query query = pm.newQuery(
  "javax.jdo.query.SQL",
  "select * from product_item where price < 10");

Если мы не указываем язык, по умолчанию используется JDOQL:

Query query = pm.newQuery(
  "SELECT FROM com.example.jdo.query.ProductItem WHERE price < 10");

3.2. Создание именованного запроса

Мы также можем определить запрос и ссылаться на него по сохраненному имени.

Для этого мы сначала создаем классProductItem:

@PersistenceCapable
public class ProductItem {

    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.INCREMENT)
    int id;
    String name;
    String status;
    String description;
    double price;

    //standard getters, setters & constructors
}

Затем мы добавляем конфигурацию класса в файлMETA-INF/package.jdo, чтобы определить запрос и назвать его:


    
        
            
            
            
        
    

Мы определили запрос с именем «PriceBelow10″.

Мы можем использовать это в нашем коде:

Query query = pm.newNamedQuery(
  ProductItem.class, "PriceBelow10");
List items = query.executeList();

3.3. ЗакрытиеQuery

Для экономии ресурсов мы можем закрыть запросы:

query.close();

Точно так же мы можем закрыть определенный набор результатов, передав его в качестве параметра методуclose():

query.close(ResultSet);

3.4. СоставлениеQuery

Если мы хотим проверить запрос, мы можем вызвать методcompile():

query.compile();

Если запрос недействителен, метод выдастJDOException.

4. JDOQL

JDOQL - это объектно-ориентированный язык запросов, разработанный для обеспечения возможностей языка SQL и сохранения отношений объектов Java в модели приложения.

Запросы JDOQL можно определять в формеsingle-String.

Прежде чем мы погрузимся глубже, давайте рассмотрим некоторые основные концепции:

4.1. Кандидатский класс

Класс-кандидат в JDOQL должен быть постоянным классом. Мы используем полное имя класса вместо имени таблицы в языке SQL:

Query query = pm.newQuery("SELECT FROM com.example.jdo.query.ProductItem");
List r = query.executeList();

Как мы видим в приведенном выше примере,com.example.jdo.query.ProductItem здесь является классом-кандидатом.

4.2. Фильтр

Фильтр может быть написан на Java, но должен принимать логическое значение:

Query query = pm.newQuery("SELECT FROM com.example.jdo.query.ProductItem");
query.setFilter("status == 'SoldOut'");
List result = query.executeList();

4.3. методы

JDOQL не поддерживает все методы Java, но поддерживает различные методы, которые мы можем вызвать из запроса и которые могут использоваться в широком диапазоне:

query.setFilter("this.name.startsWith('supported')");

Для получения дополнительной информации о поддерживаемых методах, пожалуйста, проверьте этотlink.

4.4. параметры

Мы можем передавать значения в запросы в качестве параметров. Мы можем определить параметры явно или неявно.

Чтобы определить параметр явно:

Query query = pm.newQuery(
  "SELECT FROM com.example.jdo.query.ProductItem "
  + "WHERE price < threshold PARAMETERS double threshold");
List result = (List) query.execute(10);

Этого также можно добиться с помощью методаsetParameters:

Query query = pm.newQuery(
  "SELECT FROM com.example.jdo.query.ProductItem "
  + "WHERE price < :threshold");
query.setParameters("double threshold");
List result = (List) query.execute(10);

Мы можем сделать это неявно, не определяя тип параметра:

Query query = pm.newQuery(
  "SELECT FROM com.example.jdo.query.ProductItem "
  + "WHERE price < :threshold");
List result = (List) query.execute(10);

5. Типизированный JDOQL

Чтобы использовать JDOQLTypedQueryAPI, нам нужно подготовить среду.

5.1. Maven Setup


    org.datanucleus
    datanucleus-jdo-query
    5.0.2

...

    
        maven-compiler-plugin
        
            1.8
            1.8
        
    

Последние версии этих зависимостей:datanucleus-jdo-query иmaven-compiler-plugin..

5.2. Включение обработки аннотаций

Для Eclipse мы можем выполнить следующие шаги, чтобы включить аннотированную обработку:

  1. Перейдите кJava Compiler и убедитесь, что уровень соответствия компилятора 1,8 или выше.

  2. Перейдите кJava Compiler → Annotation Processing и включите специальные настройки проекта и включите обработку аннотаций.

  3. Перейдите кJava Compiler → Annotation Processing → Factory Path, включите специальные настройки проекта и затем добавьте следующие банки в список:javax.jdo.jar,datanucleus-jdo-query.jar

Вышеупомянутая подготовка означает, что всякий раз, когда мы компилируем устойчивые классы, процессор аннотаций в datanucleus-jdo-query.jar будет генерировать класс запроса для каждого класса, аннотированного@PersistenceCapable.

В нашем случае процессор генерирует классQProductItem. Сгенерированный класс имеет почти то же имя, что и постоянный класс, но с префиксом Q.

5.3. Создать типизированный запрос JDOQL:

JDOQLTypedQuery tq = pm.newJDOQLTypedQuery(ProductItem.class);
QProductItem cand = QProductItem.candidate();
tq = tq.filter(cand.price.lt(10).and(cand.name.startsWith("pro")));
List results = tq.executeList();

Мы можем использовать класс запроса для доступа к полям-кандидатам и использовать его доступные методы Java.

6. SQL

JDO поддерживает язык SQL на случай, если мы используем RDBMS.

Создадим 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 results = query.executeList();

Мы использовалиsetClass() для запроса, чтобы получить объектыProductItem, когда мы выполняем запрос. В противном случае он получает типObject.

7. JPQL

JDO DataNucleus предоставляет язык JPQL.

Давайте создадим запрос с использованием JPQL:

Query query = pm.newQuery("JPQL","select i from "
  + "com.example.jdo.query.ProductItem i where i.price < 10"
  + " and i.status = 'InStock'");
List results = (List) query.execute();

Имя объекта здесьcom.example.jdo.query.ProductItem.. Мы не можем использовать только имя класса. Это связано с тем, что JDO не имеет метаданных для определения имени объекта, такого как JPA.. Мы определилиProductItemp, и после этого мы можем использоватьp как псевдоним для ссылки наProductItem.

Для получения дополнительных сведений о синтаксисе JPQL, пожалуйста, проверьте этотlink.

8. Заключение

В этой статье мы показали разные языки запросов, которые поддерживаются JDO. Мы показали, как сохранить именованные запросы для повторного использования, и объяснили концепции JDOQL и показали, как использовать SQL и JPQL с JDO.

Примеры кода в статье можно найтиover on GitHub.