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

Введение в Apache Cayenne ORM

Узнайте, как взаимодействовать с базой данных MySQL с помощью Apache Cayenne ORM.

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

1. Обзор

Apache Cayenne -это библиотека с открытым исходным кодом, распространяемая под лицензией Apache, предоставляющая такие функции, как инструмент моделирования, объектно-реляционное отображение, известное как ORM, для локальных операций персистентности и удаленных служб.

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

2. Зависимости Maven

Для начала нам просто нужно добавить следующие зависимости, чтобы вызвать Apache Cayenne и MySQL connector драйвер JDBC вместе для доступа к нашей базе данных intro_cayenne :


    org.apache.cayenne
    cayenne-server
    4.0.M5


    mysql
    mysql-connector-java
    5.1.44
    runtime

Давайте настроим плагин Cayenne modeler, который будет использоваться для проектирования или настройки нашего файла сопоставления, который действует как мост между схемой базы данных и объектом Java:


    org.apache.cayenne.plugins
    maven-cayenne-modeler-plugin
    4.0.M5

Вместо того чтобы создавать XML-файл сопоставления вручную (делается редко), рекомендуется использовать modeler, который является довольно продвинутым инструментом, поставляемым вместе с дистрибутивом Cayenne.

Он доступен для загрузки из этого архива в зависимости от вашей операционной системы или просто используйте кросс-платформенную версию (JAR), включенную в качестве плагина Maven.

В центральном репозитории Maven хранятся последние версии Apache Cayenne , his modeler и MySQL Connector .

Далее давайте построим наш проект с помощью mvn install и запустим графический интерфейс modeler с помощью команды mvn cayenne-modeler:run , чтобы получить в качестве вывода этот экран:

3. Настройка

Чтобы заставить Apache Cayenne искать правильную локальную базу данных, нам просто нужно заполнить его конфигурационный файл правильным драйвером, URL-адресом и пользователем в файле cayenne-project.xml находится в каталоге ресурсы :



    
        
            
            
            
            
        
    

Здесь мы можем видеть, что:

  • Локальная база данных называется intro_cayenne
  • Если он еще не создан, Кайенна сделает это за нас
  • Мы подключимся, используя имя пользователя root и пароль root (измените его в соответствии с пользователями, зарегистрированными в вашей системе управления базами данных)

Внутренне это XMLPoolingDataSourceFactory ответственный за загрузку информации о соединении JDBC из XML-ресурса, связанного с DataNodeDescriptor .

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

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

4. Картографирование и Проектирование баз данных

4.1. Моделирование

Давайте теперь нажмем на “Открыть проект” , перейдем в папку ресурсов проекта и выберем файл cayenne-project.xml, моделист покажет это:

Здесь у нас есть выбор: либо создать нашу картографическую структуру из существующей базы данных, либо действовать вручную. Эта статья будет обрабатывать тот, который использует модельер и существующую базу данных, чтобы попасть в Cayenne и быстро узнать, как он работает.

Давайте взглянем на нашу базу данных intro_cayenne , которая имеет отношение один ко многим между двумя таблицами, поскольку автор может публиковать или владеть многими статьями:

  • автор: id (PK) и имя
  • статья: id (PK), название, содержание и author_id(FK)

Теперь давайте перейдем к ” Tools > Reengineer Database Schema “, и все наши конфигурации отображения будут заполнены автоматически. На экране приглашения просто заполните конфигурацию источника данных, доступную там, в cayenne-project.xml файл и нажмите продолжить:

На следующем экране нам нужно проверить “Использовать примитивные типы Java” следующим образом:

Нам также нужно убедиться, что мы поместили com.baeldung.apache cayenne.persistent как Java-пакет и сохранили его; мы увидим, что XML-файл конфигурации был обновлен для его свойства defaultPackage в соответствии с Java-пакетом:

В каждом ObjEctity мы должны указать пакет для подклассов, как показано на следующем рисунке, и снова нажать на значок “сохранить” :

Теперь в меню “Инструменты > Генерировать классы” выберите ” Стандартные постоянные объекты ” в качестве типа; а на вкладке “Классы” проверьте все классы и нажмите “генерировать” .

Давайте вернемся к исходному коду, чтобы увидеть, что наши постоянные объекты были успешно сгенерированы, говоря о _Article.java и _Author.java .

Обратите внимание, что все эти конфигурации сохраняются в файле datamap.map.xml также находится в папке resources .

4.2. Структура Отображения

Сгенерированный файл сопоставления XML, представленный в папке ресурсов, использует некоторые уникальные теги относительно Apache Cayenne:

  • DataNode() – модель базы данных, ее содержимое вся информация, необходимая для подключения к базе данных (имя базы данных, драйвер и учетные данные пользователя)
  • DataMap() – это контейнер постоянных сущностей с их отношениями
  • DbAttribute() – представляет столбец в таблице базы данных
  • DbEntity() – модель одной таблицы базы данных или представления, она может иметь атрибуты DbAttributes и отношения
  • ObjEntity() – модель одного персистентного класса java; состоит из атрибутов ObjAttributes, соответствующих свойствам класса сущностей, и отношений ObjRelationships, которые являются свойствами, имеющими тип другой сущности
  • Embeddable() – модель класса Java, которая действует как свойство ObjEctity, но соответствует нескольким столбцам в базе данных
  • Процедура() – регистрация хранимой процедуры в базе данных
  • Query() – модель запроса, используемая для отображения запроса в конфигурационном файле без забывания о том, что мы также можем сделать это в коде

Вот полные подробности .

5. Cayenne API

Единственный оставшийся шаг-использовать API Cayenne для выполнения операций с базой данных с использованием сгенерированных классов, зная, что подклассы наших постоянных классов-это просто лучшая практика, используемая для дальнейшей настройки модели.

5.1. Создание объекта

Здесь мы просто сохраняем объект Author и позже проверяем, что в базе данных есть только одна запись этого типа:

@Test
public void whenInsert_thenWeGetOneRecordInTheDatabase() {
    Author author = context.newObject(Author.class);
    author.setName("Paul");

    context.commitChanges();

    long records = ObjectSelect.dataRowQuery(Author.class)
      .selectCount(context);
 
    assertEquals(1, records);
}

5.2. Чтение объекта

После сохранения Author мы просто выбираем его среди других с помощью простого запроса по определенному свойству:

@Test
public void whenInsert_andQueryByFirstName_thenWeGetTheAuthor() {
    Author author = context.newObject(Author.class);
    author.setName("Paul");

    context.commitChanges();

    Author expectedAuthor = ObjectSelect.query(Author.class)
      .where(Author.NAME.eq("Paul"))
      .selectOne(context);

    assertEquals("Paul", expectedAuthor.getName());
}

5.3. Извлечение всех записей класса

Мы собираемся сохранить двух авторов и получить коллекцию авторских объектов, чтобы проверить, что есть только эти два сохраненных объекта:

@Test
public void whenInsert_andQueryAll_thenWeGetTwoAuthors() {
    Author firstAuthor = context.newObject(Author.class);
    firstAuthor.setName("Paul");

    Author secondAuthor = context.newObject(Author.class);
    secondAuthor.setName("Ludovic");

    context.commitChanges();

    List authors = ObjectSelect
      .query(Author.class)
      .select(context);
 
    assertEquals(2, authors.size());
}

5.4. Обновление объекта

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

@Test
public void whenUpdating_thenWeGetAnUpatedeAuthor() {
    Author author = context.newObject(Author.class);
    author.setName("Paul");
    context.commitChanges();

    Author expectedAuthor = ObjectSelect.query(Author.class)
      .where(Author.NAME.eq("Paul"))
      .selectOne(context);
    expectedAuthor.setName("Garcia");
    context.commitChanges();

    assertEquals(author.getName(), expectedAuthor.getName());
}

5.5. Прикрепление объекта

Мы можем назначить статью автору:

@Test
public void whenAttachingToArticle_thenTheRelationIsMade() {
    Author author = context.newObject(Author.class);
    author.setName("Paul");

    Article article = context.newObject(Article.class);
    article.setTitle("My post title");
    article.setContent("The content");
    article.setAuthor(author);

    context.commitChanges();

    Author expectedAuthor = ObjectSelect.query(Author.class)
      .where(Author.NAME.eq("Smith"))
      .selectOne(context);

    Article expectedArticle = (expectedAuthor.getArticles()).get(0);
 
    assertEquals(article.getTitle(), expectedArticle.getTitle());
}

5.6. Удаление объекта

Удаление сохраненного объекта полностью удаляет его из базы данных, после чего мы увидим null в результате запроса:

@Test
public void whenDeleting_thenWeLostHisDetails() {
    Author author = context.newObject(Author.class);
    author.setName("Paul");
    context.commitChanges();

    Author savedAuthor = ObjectSelect.query(Author.class)
      .where(Author.NAME.eq("Paul"))
      .selectOne(context);
    if(savedAuthor != null) {
        context.deleteObjects(author);
        context.commitChanges();
    }

    Author expectedAuthor = ObjectSelect.query(Author.class)
      .where(Author.NAME.eq("Paul"))
      .selectOne(context);
 
    assertNull(expectedAuthor);
}

5.7. Удалить все Записи Класса

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

@After
public void deleteAllRecords() {
    SQLTemplate deleteArticles = new SQLTemplate(
      Article.class, "delete from article");
    SQLTemplate deleteAuthors = new SQLTemplate(
      Author.class, "delete from author");

    context.performGenericQuery(deleteArticles);
    context.performGenericQuery(deleteAuthors);
}

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

В этом уроке мы сосредоточились на использовании Apache Cayenne ORM, чтобы легко продемонстрировать, как выполнять операции CRUD с отношением один ко многим .

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