Рубрики
Без рубрики

Расширенный запрос в Apache Cayenne

Узнайте, как писать простые и продвинутые запросы с помощью Apache Cayenne.

Автор оригинала: baeldung.

1. Обзор

Ранее мы сосредоточились на том, как начать работу с Apache Cayenne.

В этой статье мы покроем, как писать простые и продвинутые запросы с ORM.

2. Настройка

Настройка аналогична установке, используемой в предыдущей статье.

Кроме того, перед каждым тестом мы спасаем трех авторов и в конце удаляем их:

  • Пол Ксавье
  • pAuL Смит
  • Вики Сарра

3. ОбъектИзбирать

Давайте начнем просто, и посмотрите, как мы можем получить все авторы с именами, содержащими “Пол”:

@Test
public void whenContainsObjS_thenWeGetOneRecord() {
    List authors = ObjectSelect.query(Author.class)
      .where(Author.NAME.contains("Paul"))
      .select(context);

    assertEquals(authors.size(), 1);
}

Далее давайте посмотрим, как мы можем применить нечувствительный к делу тип запроса LIKE в столбце имени Автора:

@Test
void whenLikeObjS_thenWeGetTwoAuthors() {
    List authors = ObjectSelect.query(Author.class)
      .where(Author.NAME.likeIgnoreCase("Paul%"))
      .select(context);

    assertEquals(authors.size(), 2);
}

Далее, endsWith () выражение вернет только одну запись, так как только один автор имеет соответствующее имя:

@Test
void whenEndsWithObjS_thenWeGetOrderedAuthors() {
    List authors = ObjectSelect.query(Author.class)
      .where(Author.NAME.endsWith("Sarra"))
      .select(context);
    Author firstAuthor = authors.get(0);

    assertEquals(authors.size(), 1);
    assertEquals(firstAuthor.getName(), "Vicky Sarra");
}

Более сложным является запрос авторов, имена которых находятся в списке:

@Test
void whenInObjS_thenWeGetAuthors() {
    List names = Arrays.asList(
      "Paul Xavier", "pAuL Smith", "Vicky Sarra");
 
    List authors = ObjectSelect.query(Author.class)
      .where(Author.NAME.in(names))
      .select(context);

    assertEquals(authors.size(), 3);
}

нин один из них наоборот, здесь только “Вики” будет присутствовать в результате:

@Test
void whenNinObjS_thenWeGetAuthors() {
    List names = Arrays.asList(
      "Paul Xavier", "pAuL Smith");
    List authors = ObjectSelect.query(Author.class)
      .where(Author.NAME.nin(names))
      .select(context);
    Author author = authors.get(0);

    assertEquals(authors.size(), 1);
    assertEquals(author.getName(), "Vicky Sarra");
}

Обратите внимание, что эти два следующих кода одинаковы, поскольку они оба создадут выражение одного и того же типа с одним и тем же параметром:

Expression qualifier = ExpressionFactory
  .containsIgnoreCaseExp(Author.NAME.getName(), "Paul");
Author.NAME.containsIgnoreCase("Paul");

Вот список некоторых доступных выражений в Выражение и ВыражениеФактория классы :

  • какExp : для построения выражения LIKE
  • какIgnoreCaseExp : используется для построения LIKE_IGNORE_CASE выражения
  • содержитExp : выражение для запроса LIKE с шаблоном, соответствующим где угодно в строке
  • содержитIgnoreCaseExp : так же, как содержитExp но с использованием бесчувственного подхода
  • начинаетсяСЭксп : шаблон должен соответствовать началу строки
  • начинаетсяСИгиньоCaseExp : похож на начинаетсяСЭксп но с использованием бесчувственного подхода
  • endsWithExp : выражение, которое соответствует концу строки
  • endsWithIgnoreCaseExp : выражение, которое соответствует концу строки с использованием бесчувственного подхода
  • expTrue : для булеаных истинное выражение
  • expFalse : для булеаных ложные выражение
  • иExp : используется для цепочки двух выражений с и оператор
  • orExp : приковать два выражения с помощью или оператор

Более письменные тесты доступны в коде источника статьи, пожалуйста, проверьте Гитхуб хранилище.

4. Выберите Керри

Это самый широкий тип запросов в пользовательских приложениях. Выберите Квери описывает простой и мощный API, который действует как синтаксис S’L, но все же с Java-объектами и методами, которые следуют с шаблонами строителя для построения более сложных выражений.

Здесь мы говорим о языке выражения, где мы строим запросы, используя оба Выражение (для построения выражений) ака квалификатора и Заказ (для сортировки результатов) классы, которые затем преобразуются в родной S’L ORM.

Чтобы увидеть это в действии, мы собрали несколько тестов, которые показывают на практике, как построить некоторые выражения и сортировки данных.

Давайте применим запрос LIKE, чтобы получить Авторы с именем, как “Пол” :

@Test
void whenLikeSltQry_thenWeGetOneAuthor() {
    Expression qualifier 
      = ExpressionFactory.likeExp(Author.NAME.getName(), "Paul%");
    SelectQuery query 
      = new SelectQuery(Author.class, qualifier);
    
    List authorsTwo = context.performQuery(query);

    assertEquals(authorsTwo.size(), 1);
}

Это означает, что если вы не предоставляете какое-либо выражение запроса ( Выберите Квери ), результатом будут все записи таблицы Автор.

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

@Test
void whenCtnsIgnorCaseSltQry_thenWeGetTwoAuthors() {
    Expression qualifier = ExpressionFactory
      .containsIgnoreCaseExp(Author.NAME.getName(), "Paul");
    SelectQuery query 
      = new SelectQuery(Author.class, qualifier);
    
    List authors = context.performQuery(query);

    assertEquals(authors.size(), 2);
}

Аналогичным образом, давайте авторов с именами, содержащими “Пол”, в случае бесчувственным образом ( содержитIgnoreCaseExp ) и с именем, которое заканчивается ( endsWithExp ) с буквой h:

@Test
void whenCtnsIgnorCaseEndsWSltQry_thenWeGetTwoAuthors() {
    Expression qualifier = ExpressionFactory
      .containsIgnoreCaseExp(Author.NAME.getName(), "Paul")
      .andExp(ExpressionFactory
        .endsWithExp(Author.NAME.getName(), "h"));
    SelectQuery query = new SelectQuery(
      Author.class, qualifier);
    List authors = context.performQuery(query);

    Author author = authors.get(0);

    assertEquals(authors.size(), 1);
    assertEquals(author.getName(), "pAuL Smith");
}

Восходящий порядок может быть выполнен с помощью Заказ класс:

@Test
void whenAscOrdering_thenWeGetOrderedAuthors() {
    SelectQuery query = new SelectQuery(Author.class);
    query.addOrdering(Author.NAME.asc());
 
    List authors = query.select(context);
    Author firstAuthor = authors.get(0);

    assertEquals(authors.size(), 3);
    assertEquals(firstAuthor.getName(), "Paul Xavier");
}

Здесь вместо того, чтобы query.addOrdering (Author.NAME.asc()), мы также можем просто использовать Сортировка класс, чтобы получить восходящий порядок:

query.addOrdering(Author.NAME.getName(), SortOrder.ASCENDING);

Относительно есть нисходящий заказ:

@Test
void whenDescOrderingSltQry_thenWeGetOrderedAuthors() {
    SelectQuery query = new SelectQuery(Author.class);
    query.addOrdering(Author.NAME.desc());

    List authors = query.select(context);
    Author firstAuthor = authors.get(0);

    assertEquals(authors.size(), 3);
    assertEquals(firstAuthor.getName(), "pAuL Smith");
}

Как мы видели в предыдущем примере – еще один способ установить этот заказ:

query.addOrdering(Author.NAME.getName(), SortOrder.DESCENDING);

5. S’LTemplate

S’LTemplate также является одной из альтернатив, которые мы можем использовать с Cayenne, чтобы не использовать запросы в стиле объектов.

Создание запросов с S’LTemplate является непосредственно относительным для записи родных заявлений S’L с некоторыми параметрами. Давайте реализуем несколько быстрых примеров.

Вот как мы удаляем всех авторов после каждого теста:

@After
void deleteAllAuthors() {
    SQLTemplate deleteAuthors = new SQLTemplate(
      Author.class, "delete from author");
    context.performGenericQuery(deleteAuthors);
}

Чтобы найти всех зарегистрированных Авторов, нам просто нужно применить запрос на S’L выбрать из авторского и мы непосредственно увидим, что результат правильный, так как у нас есть ровно три сохраненных автора:

@Test
void givenAuthors_whenFindAllSQLTmplt_thenWeGetThreeAuthors() {
    SQLTemplate select = new SQLTemplate(
      Author.class, "select * from Author");
    List authors = context.performQuery(select);

    assertEquals(authors.size(), 3);
}

Далее, давайте автор с именем “Вики Сарра”:

@Test
void givenAuthors_whenFindByNameSQLTmplt_thenWeGetOneAuthor() {
    SQLTemplate select = new SQLTemplate(
      Author.class, "select * from Author where name = 'Vicky Sarra'");
    List authors = context.performQuery(select);
    Author author = authors.get(0);

    assertEquals(authors.size(), 1);
    assertEquals(author.getName(), "Vicky Sarra");
}

6. ЭйБЮли Квери

Далее, давайте запрашивать данные через ЭйБЗЛКвери, который был создан в рамках эксперимента по принятию API Java Persistence в Cayenne.

Здесь запросы применяются в стиле параметриза; Давайте рассмотрим некоторые практические примеры.

Во-первых, поиск всех сохраненных авторов будет выглядеть так:

@Test
void givenAuthors_whenFindAllEJBQL_thenWeGetThreeAuthors() {
    EJBQLQuery query = new EJBQLQuery("select a FROM Author a");
    List authors = context.performQuery(query);

    assertEquals(authors.size(), 3);
}

Давайте искать автора снова с именем “Вики Сарра”, но теперь с ЭйБЮли Квери :

@Test
void givenAuthors_whenFindByNameEJBQL_thenWeGetOneAuthor() {
    EJBQLQuery query = new EJBQLQuery(
      "select a FROM Author a WHERE a.name = 'Vicky Sarra'");
    List authors = context.performQuery(query);
    Author author = authors.get(0);

    assertEquals(authors.size(), 1);
    assertEquals(author.getName(), "Vicky Sarra");
}

Еще лучшим примером является обновление автора:

@Test
void whenUpdadingByNameEJBQL_thenWeGetTheUpdatedAuthor() {
    EJBQLQuery query = new EJBQLQuery(
      "UPDATE Author AS a SET a.name "
      + "= 'Vicky Edison' WHERE a.name = 'Vicky Sarra'");
    QueryResponse queryResponse = context.performGenericQuery(query);

    EJBQLQuery queryUpdatedAuthor = new EJBQLQuery(
      "select a FROM Author a WHERE a.name = 'Vicky Edison'");
    List authors = context.performQuery(queryUpdatedAuthor);
    Author author = authors.get(0);

    assertNotNull(author);
}

Если мы просто хотим выбрать столбец, мы должны использовать этот запрос “выберите a.name от автора a” . Другие примеры приведены в исходным кодом статьи на Гитхуб .

7. S’LExec

СЛЭксек также новый беглый запрос API, представленный из версии M4 Cayenne.

Простая вставка выглядит так:

@Test
void whenInsertingSQLExec_thenWeGetNewAuthor() {
    int inserted = SQLExec
      .query("INSERT INTO Author (name) VALUES ('Baeldung')")
      .update(context);

    assertEquals(inserted, 1);
}

Далее мы можем обновить автора на основе его имени:

@Test
void whenUpdatingSQLExec_thenItsUpdated() {
    int updated = SQLExec.query(
      "UPDATE Author SET name = 'Baeldung' "
      + "WHERE name = 'Vicky Sarra'")
      .update(context);

    assertEquals(updated, 1);
}

Мы можем получить более подробную информацию из документация .

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

В этой статье мы рассмотрели несколько способов написания простых и более продвинутых запросов с помощью Cayenne.

Как всегда, исходный код этой статьи можно найти более на GitHub .