1. Обзор
Eclipse JNoSQL — это набор API и реализаций, упрощающих взаимодействие Java-приложений с базами данных NoSQL .
В этой статье мы узнаем, как установить и настроить JNoSQL для взаимодействия с базой данных NoSQL. Мы будем работать как с коммуникационным, так и с картографическим слоем.
2. Коммуникационный уровень Eclipse JNoSQL
С технической точки зрения коммуникационный уровень состоит из двух модулей: Diana API и драйвера.
Хотя API определяет абстракцию для типов баз данных NoSQL, драйвер предоставляет реализации для большинства известных баз данных .
Мы можем сравнить это с JDBC API и драйвером JDBC в реляционных базах данных.
2.1. Eclipse JNoSQL Диана API
Проще говоря, существует четыре основных типа баз данных NoSQL: Key-Value, Column, Document и Graph.
И Eclipse JNoSQL Diana API определяет три модуля:
- Диана-ключ-значение
- диана-колонна
- Диана-документ
Тип графа NoSQL не поддерживается API, поскольку он уже поддерживается Apache ThinkerPop .
API основан на базовом модуле diana-core и определяет абстракцию общих понятий, таких как конфигурация, фабрика, менеджер, сущность и значение.
Для работы с API нам нужно предоставить зависимость соответствующего модуля от нашего типа базы данных NoSQL.
Таким образом, для документо-ориентированной базы данных нам понадобится зависимость diana-document :
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-document</artifactId>
<version>0.0.6</version>
</dependency>
Точно так же мы должны использовать модуль diana-ключ-значение
, если рабочая база данных NoSQL ориентирована на ключ-значение:
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-key-value</artifactId>
<version>0.0.6</version>
</dependency>
И, наконец, модуль diana-column
, если он ориентирован на столбцы:
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-column</artifactId>
<version>0.0.6</version>
</dependency>
Самые свежие версии можно найти на Maven Central .
2.2. Драйвер Eclipse JNoSQL Диана
Драйвер представляет собой набор реализаций API для наиболее распространенных баз данных NoSQL .
Для каждой базы данных NoSQL существует одна реализация. Если база данных является многомодельной, драйвер должен реализовать все поддерживаемые API .
Например, cockbase-driver
реализует как diana-document,
так и diana-key-value,
потому что Couchbase ориентирован как на документ, так и на ключ-значение.
В отличие от реляционных баз данных, где драйвер обычно предоставляется поставщиком базы данных, здесь драйвер предоставляется Eclipse JNoSQL . В большинстве случаев этот драйвер представляет собой оболочку официальной библиотеки производителя.
Чтобы начать работу с драйвером, мы должны включить API и соответствующую реализацию для выбранной базы данных NoSQL.
Например, для MongoDB нам нужно включить следующие зависимости:
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-document</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>mongodb-driver</artifactId>
<version>0.0.6</version>
</dependency>
Процесс работы с драйвером прост.
Во-первых, нам нужен bean-компонент конфигурации
. Прочитав файл конфигурации из пути к классам или значений жесткого кодирования, конфигурация
может создать фабрику.
Затем мы используем его для создания Manager.
Наконец, менеджер
отвечает за отправку и извлечение Entity
из базы данных NoSQL .
В следующих подразделах мы объясним этот процесс для каждого типа базы данных NoSQL.
2.3. Работа с документно-ориентированной базой данных
В этом примере мы будем использовать встроенную базу данных MongoDB , так как с ней легко начать работу и она не требует установки. Она ориентирована на документы, и следующие инструкции применимы к любой другой базе данных NoSQL, ориентированной на документы.
В самом начале мы должны предоставить все необходимые настройки, необходимые приложению для правильного взаимодействия с базой данных .
В самой элементарной форме мы должны указать хост
и порт
работающего экземпляра MongoDB.
Мы можем предоставить эти настройки либо в mongodb-driver.properties,
расположенном в пути к классам:
#Define Host and Port
mongodb-server-host-1=localhost:27017
Или как жестко закодированные значения:
Map<String, Object> map = new HashMap<>();
map.put("mongodb-server-host-1", "localhost:27017");
Затем мы создаем компонент конфигурации
для типа документа:
DocumentConfiguration configuration = new MongoDBDocumentConfiguration();
Из этого компонента конфигурации
мы можем создать ManagerFactory
:
DocumentCollectionManagerFactory managerFactory = configuration.get();
Неявно метод get () компонента
Configuration
использует настройки из файла свойств. Мы также можем получить эту фабрику из жестко заданных значений:
DocumentCollectionManagerFactory managerFactory
= configuration.get(Settings.of(map));
У ManagerFactory
есть простой метод get(),
который принимает имя базы данных в качестве параметра и создает Manager
:
DocumentCollectionManager manager = managerFactory.get("my-db");
И, наконец, мы готовы. Менеджер предоставляет
все необходимые методы для взаимодействия с базовой базой данных NoSQL через DocumentEntity.
Итак, мы могли бы, например, вставить документ:
DocumentEntity documentEntity = DocumentEntity.of("books");
documentEntity.add(Document.of("_id", "100"));
documentEntity.add(Document.of("name", "JNoSQL in Action"));
documentEntity.add(Document.of("pages", "620"));
DocumentEntity saved = manager.insert(documentEntity);
Мы также можем искать документы:
DocumentQuery query = select().from("books").where("_id").eq(100).build();
List<DocumentEntity> entities = manager.select(query);
И аналогичным образом мы могли бы обновить существующий документ:
saved.add(Document.of("author", "foreach"));
DocumentEntity updated = manager.update(saved);
И, наконец, мы можем удалить сохраненный документ:
DocumentDeleteQuery deleteQuery = delete().from("books").where("_id").eq("100").build();
manager.delete(deleteQuery);
Чтобы запустить пример, нам просто нужно получить доступ к модулю jnosql-diana
и запустить приложение DocumentApp
.
Мы должны увидеть вывод в консоли:
DefaultDocumentEntity{documents={pages=620, name=JNoSQL in Action, _id=100}, name='books'}
DefaultDocumentEntity{documents={pages=620, author=foreach, name=JNoSQL in Action, _id=100}, name='books'}
[]
2.4. Работа с базой данных, ориентированной на столбцы
В этом разделе мы будем использовать встроенную версию базы данных Cassandra , поэтому установка не требуется.
Процесс работы с базой данных, ориентированной на столбцы, очень похож. Первым делом добавляем в pom драйвер Cassandra и API колонки:
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-column</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>cassandra-driver</artifactId>
<version>0.0.6</version>
</dependency>
Далее нам нужны параметры конфигурации, указанные в файле конфигурации diana-cassandra.properties
в пути к классам. В качестве альтернативы мы могли бы также использовать жестко заданные значения конфигурации.
Затем, используя аналогичный подход, мы создадим ColumnFamilyManager
и начнем манипулировать ColumnEntity:
ColumnConfiguration configuration = new CassandraConfiguration();
ColumnFamilyManagerFactory managerFactory = configuration.get();
ColumnFamilyManager entityManager = managerFactory.get("my-keySpace");
Итак, чтобы создать новый объект, давайте вызовем метод insert()
:
ColumnEntity columnEntity = ColumnEntity.of("books");
Column key = Columns.of("id", 10L);
Column name = Columns.of("name", "JNoSQL in Action");
columnEntity.add(key);
columnEntity.add(name);
ColumnEntity saved = entityManager.insert(columnEntity);
Чтобы запустить пример и просмотреть выходные данные в консоли, запустите приложение ColumnFamilyApp
.
2.5. Работа с базой данных, ориентированной на ключ-значение
В этом разделе мы будем использовать Hazelcast. Hazelcast — это база данных NoSQL, ориентированная на ключ-значение . Для получения дополнительной информации о базе данных Hazelcast вы можете проверить эту ссылку .
Процесс работы с типом, ориентированным на ключ-значение, также аналогичен. Начнем с добавления этих зависимостей в pom:
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>diana-key-value</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>hazelcast-driver</artifactId>
<version>0.0.6</version>
</dependency>
Затем нам нужно указать параметры конфигурации. Затем мы можем получить BucketManager
, а затем манипулировать KeyValueEntity:
KeyValueConfiguration configuration = new HazelcastKeyValueConfiguration();
BucketManagerFactory managerFactory = configuration.get();
BucketManager entityManager = managerFactory.getBucketManager("books");
Допустим, мы хотим сохранить следующую модель Book :
public class Book implements Serializable {
private String isbn;
private String name;
private String author;
private int pages;
// standard constructor
// standard getters and setters
}
Итак, мы создаем экземпляр Book
, а затем сохраняем его, вызывая метод put()
;
Book book = new Book(
"12345", "JNoSQL in Action",
"foreach", 420);
KeyValueEntity keyValueEntity = KeyValueEntity.of(
book.getIsbn(), book);
entityManager.put(keyValueEntity);
Затем, чтобы получить сохраненный экземпляр книги :
Optional<Value> optionalValue = manager.get("12345");
Value value = optionalValue.get(); // or any other adequate Optional handling
Book savedBook = value.get(Book.class);
Чтобы запустить пример и просмотреть выходные данные в консоли, запустите приложение KeyValueApp
.
3. Уровень отображения Eclipse JNoSQL
Уровень сопоставления, Artemis API, представляет собой набор API-интерфейсов, которые помогают сопоставлять объекты с аннотациями Java с базами данных NoSQL . Он основан на API-интерфейсе Diana и CDI (внедрение контекста и зависимостей).
Мы можем рассматривать этот API как JPA или ORM, как в мире NoSQL . Этот уровень также предоставляет API для каждого типа NoSQL и один основной API для общих функций.
В этом разделе мы будем работать с документно-ориентированной базой данных MongoDB.
3.1. Требуемые зависимости
Чтобы включить Artemis в приложении, нам нужно добавить зависимость artemis-configuration .
Поскольку MongoDB ориентирована на документы , также необходима зависимость artemis-document .
Для других типов баз данных NoSQL мы будем использовать artemis-column, artemis-key-value
и artemis-graph
.
Также необходим драйвер Diana для MongoDB:
<dependency>
<groupId>org.jnosql.artemis</groupId>
<artifactId>artemis-configuration</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.jnosql.artemis</groupId>
<artifactId>artemis-document</artifactId>
<version>0.0.6</version>
</dependency>
<dependency>
<groupId>org.jnosql.diana</groupId>
<artifactId>mongodb-driver</artifactId>
<version>0.0.6</version>
</dependency>
Artemis основан на CDI, поэтому нам также необходимо предоставить эту зависимость от Maven:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
3.2. Файл конфигурации документа
Конфигурация — это набор свойств для данной базы данных, которые позволяют нам предоставлять настройку вне кода. По умолчанию нам нужно предоставить файл jnosql.json
в ресурсе META-INF.
Это пример файла конфигурации:
[
{
"description": "The mongodb document configuration",
"name": "document",
"provider": "org.jnosql.diana.mongodb.document.MongoDBDocumentConfiguration",
"settings": {
"mongodb-server-host-1":"localhost:27019"
}
}
]
Нам нужно будет указать имя конфигурации выше, установив атрибут имени в нашем
ConfigurationUnit
.
Если конфигурация находится в другом файле, ее можно указать с помощью атрибута fileName
.
Учитывая эту конфигурацию, мы создаем фабрику:
@Inject
@ConfigurationUnit(name = "document")
private DocumentCollectionManagerFactory<MongoDBDocumentCollectionManager> managerFactory;
И из этой фабрики мы можем создать DocumentCollectionManager
:
@Produces
public MongoDBDocumentCollectionManager getEntityManager() {
return managerFactory.get("todos");
}
DocumentCollectionManager
— это компонент с поддержкой CDI, который используется как в шаблоне
, так и в репозитории.
3.3. Отображение
Сопоставление — это управляемый аннотациями процесс, посредством которого модель Entity
преобразуется в EntityValue Diana.
Начнем с определения модели Todo :
@Entity
public class Todo implements Serializable {
@Id("id")
public long id;
@Column
public String name;
@Column
public String description;
// standard constructor
// standard getters and setters
}
Как показано выше, у нас есть основные аннотации сопоставления: @Entity, @Id
и @Column.
Теперь, чтобы манипулировать этой моделью, нам нужен либо класс Template
, либо интерфейс Repository .
3.4. Работа с шаблоном
Шаблон является связующим звеном между моделью сущностей и API Diana . Для базы данных, ориентированной на документы, мы начинаем с внедрения bean- компонента DocumentTemplate
:
@Inject
DocumentTemplate documentTemplate;
И тогда мы можем манипулировать сущностью Todo .
Например, мы можем создать Todo
:
public Todo add(Todo todo) {
return documentTemplate.insert(todo);
}
Или мы можем получить Todo
по id
:
public Todo get(String id) {
Optional<Todo> todo = documentTemplate
.find(Todo.class, id);
return todo.get(); // or any other proper Optional handling
}
Чтобы выбрать все объекты, мы создаем DocumentQuery
, а затем вызываем метод select()
:
public List<Todo> getAll() {
DocumentQuery query = select().from("Todo").build();
return documentTemplate.select(query);
}
И, наконец, мы можем удалить объект Todo
по id
:
public void delete(String id) {
documentTemplate.delete(Todo.class, id);
}
3.5. Работа с репозиторием
В дополнение к классу Template
мы также можем управлять сущностями через интерфейс Repository
, который имеет методы для создания, обновления, удаления и извлечения информации.
Чтобы использовать интерфейс репозитория
, мы просто предоставляем субинтерфейс репозитория:
public interface TodoRepository extends Repository<Todo, String> {
List<Todo> findByName(String name);
List<Todo> findAll();
}
В соответствии со следующими соглашениями об именах методов и параметров реализация этого интерфейса предоставляется во время выполнения в виде компонента CDI.
В этом примере все объекты Todo
с совпадающим именем
извлекаются методом findByName()
.
Теперь мы можем использовать его:
@Inject
TodoRepository todoRepository;
Квалификатор базы данных
позволяет нам работать с более чем одной базой данных NoSQL в одном приложении. Он поставляется с двумя атрибутами, типом и поставщиком.
Если БД мультимодельная, то нам нужно указать, с какой моделью мы работаем:
@Inject
@Database(value = DatabaseType.DOCUMENT)
TodoRepository todoRepository;
Кроме того, если у нас есть более одной базы данных одной модели, нам нужно указать поставщика:
@Inject
@Database(value = DatabaseType.DOCUMENT, provider="org.jnosql.diana.mongodb.document.MongoDBDocumentConfiguration")
TodoRepository todoRepository;
Чтобы запустить пример, просто войдите в модуль jnosql-artemis и вызовите эту команду:
mvn package liberty:run
Эта команда создает, развертывает и запускает сервер Open Liberty благодаря плагину Liberty -maven-plugin .
3.6. Тестирование приложения
Поскольку приложение предоставляет конечную точку REST, мы можем использовать любой клиент REST для наших тестов. Здесь мы использовали инструмент завиток.
Итак, чтобы сохранить класс Todo:
curl -d '{"id":"120", "name":"task120", "description":"Description 120"}' -H "Content-Type: application/json" -X POST http://localhost:9080/jnosql-artemis/todos
и чтобы получить все Todo:
curl -H "Accept: application/json" -X GET http://localhost:9080/jnosql-artemis/todos
Или, чтобы получить только одно задание:
curl -H "Accept: application/json" -X GET http://localhost:9080/jnosql-artemis/todos/120
4. Вывод
В этом руководстве мы рассмотрели, как JNoSQL может абстрагировать взаимодействие с базой данных NoSQL.
Во-первых, мы использовали JNoSQL Diana API для взаимодействия с базой данных с помощью низкоуровневого кода. Затем мы использовали JNoSQL Artemis API для работы с дружественными аннотированными моделями Java .
Как обычно, мы можем найти код, использованный в этой статье , на Github .