Статьи

Celesta: API баз данных SQL, миграция схем и тестирование в одной библиотеке Java

Как и большинство проектов с открытым исходным кодом, Celesta возникла как попытка решить практическую проблему, когда не было других доступных адекватных инструментов. В этом случае необходимо было быстро создавать и развертывать большое количество небольших веб-приложений на Java, которые работают с СУБД.

Конечно, существует множество фреймворков и библиотек для решения этой проблемы, но для нас использование любой из них привело к дорогостоящей и медленной разработке. Поддержание системы миграции баз данных и создание автоматизированной системы тестирования и развертывания было трудоемким. Существующие подходы, подходящие для создания больших приложений, оказались громоздкими, когда возникла необходимость массового производства относительно небольших сервисов с использованием Spring Boot. Нам также нужно было повторно использовать код, написанный для разных проектов, в том числе для разных типов РСУБД.

И Celesta, бесплатная библиотека с открытым исходным кодом, была создана, чтобы упростить эту задачу и помочь нам сосредоточиться на бизнес-логике.

Короче говоря, Селеста это:

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

Celesta поддерживает следующие типы реляционных баз данных: PostgreSQL, MS SQL Server, Oracle, Firebird (бета) и H2.

Основные возможности Celesta:

  1. Идея очень похожа на основной принцип Java: «Пиши один раз, запускай на каждой поддерживаемой СУБД». Код бизнес-логики не знает, для какой базы данных он выполняется. Вы можете написать код бизнес-логики и запустить его на MS SQL Server, затем переключиться на PostgreSQL, и переход будет плавным. Ну, почти :).
  2. Автоматическая миграция живой базы данных. Большая часть жизненного цикла проекта Celesta происходит, когда база данных уже существует и заполняется данными для сохранения, и в то же время схема должна постоянно изменяться. Celesta может автоматически настроить структуру базы данных в соответствии с вашей схемой данных.
  3. Тестирование. Вы можете автоматически тестировать методы, изменяя данные в базе данных и делать это легко, быстро и аккуратно, не прибегая к внешним инструментам, таким как DbUnit и контейнеры.

Зачем вам нужен независимый код типа базы данных?

Не случайно мы впервые упомянули независимость кода бизнес-логики от типа СУБД — код Celesta не знает, на какой СУБД он выполняется. С чего бы это?

Прежде всего, выбор RDMBS часто является вопросом предпочтения. У наших клиентов часто есть предпочтительные RDMBS, в которые они инвестировали, и они хотят, чтобы решения разрабатывались для существующей инфраструктуры. Технологический ландшафт меняется: сегодня PostgreSQL становится все более частым, тогда как всего несколько лет назад мы увидели доминирование MS SQL Server. Celesta поддерживает наиболее широко используемые СУБД, и эти изменения нас не касаются.

Во-вторых, мы хотели повторно использовать код от проекта к проекту и создать библиотеку многократного использования. Такие вещи, как иерархические каталоги и модули доставки уведомлений по электронной почте, по сути являются стандартными, так зачем поддерживать несколько версий для клиентов с разными RDMBS?

И последнее, но не менее важное: он позволяет пользователям запускать модульные тесты без таких инструментов, как DbUnit и контейнеров, использующих встроенную базу данных H2. База данных H2 не требует установки и запускается мгновенно в режиме в памяти. Celesta быстро создает схему данных для запуска тестов и «забывания» базы данных впоследствии. 

При независимости от типа базы данных на самом деле не имеет значения, для какой базы данных выполняется бизнес-логика, поэтому, если в H2 не возникает ошибок, то же самое будет и в PostgreSQL. Конечно, команде разработчиков Celesta необходимо выполнить несколько тестов на реальной СУБД, чтобы убедиться, что платформа одинаково выполняет свой API на разных RDMBS. И мы делаем это, поэтому разработчики бизнес-логики избавлены от этой задачи.

CelestaSQL

Как достигается эта функциональность между базами данных? Естественно, цена этого — необходимость в специальном API, чтобы изолировать бизнес-логику от любых аспектов, связанных с базой данных, для работы с данными. Celesta генерирует код доступа к данным Java-классов, а для базы данных — SQL-код и некоторые вспомогательные объекты.

Celesta не допускает объектно-реляционного отображения, как есть, потому что дизайн модели данных основан на структуре базы данных, а не на классах. Т.е. сначала разрабатывается модель ER для таблиц, а затем Celesta генерирует классы доступа к данным (курсоры) в соответствии с ней.

Можно добиться одинакового поведения кода, работающего со всеми поддерживаемыми СУБД, только для функций, реализованных более или менее одинаково в каждой из них. Если мы используем диаграмму Эйлера для представления наборов функций поддерживаемых баз данных, мы получим следующий результат:

 

Эйлерова диаграмма типов СУБД

Если мы обеспечим полную независимость от типа базы данных, функциональные возможности пользователей Celesta должны лежать на пересечении всех наборов функций. И на первый взгляд это кажется серьезным ограничением. Конечно, некоторые специфические особенности, скажем, MS SQL Server, для нас недоступны. Но все реляционные базы данных поддерживают таблицы, внешние ключи, представления, последовательности и SQL-запросы с операторами JOIN и GROUP BY. Это инструменты, которые мы можем предоставить разработчикам. Мы предлагаем «обобщенный SQL», который передается в запросы SQL для соответствующих диалектов базы данных, и называем его CelestaSQL.

Язык CelestaSQL включает DDL для определения объектов базы данных и запросы SELECT для представлений и фильтров, но он не содержит команд DML — изменение выполняется курсорами, и мы рассмотрим их позже.

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

Девять типов могут показаться немногочисленными (по сравнению с числом, поддерживаемым , например, PostgreSQL ), но в действительности их достаточно для хранения финансовой, торговой и логистической информации: строки, целые числа и значения с плавающей запятой, даты, логические значения, и BLOB всегда достаточно для представления такого рода данных.

Язык CelestaSQL описан в документации, содержащей множество синтаксических диаграмм.

Модификация структуры базы данных: идемпотентный DDL

Еще одной ключевой функциональной возможностью Celesta является подход к миграции структуры производственной базы данных по мере развития проекта. Эта функция реализована с использованием встроенного подхода с использованием идемпотентного DDL.

Короче говоря, когда мы пишем следующий текст в CelestaSQL:


SQL