Reladomo (ранее известный как Mithra)-это фреймворк объектно-реляционного отображения (ORM) для Java , разработчик в Goldman Sachs , в настоящее время выпущенный как проект с открытым исходным кодом. Фреймворк предоставляет функции, обычно необходимые для ORM, а также некоторые дополнительные функции.
Давайте рассмотрим некоторые ключевые особенности Rella domo :
он может генерировать классы Java, а также сценарии DDL
он управляется метаданными, записанными в XML-файлах
сгенерированный код является расширяемым
язык запросов является объектно-ориентированным и строго типизированным
фреймворк обеспечивает поддержку сегментирования (одна и та же схема, разные наборы данных)
поддержка тестирования также включена
он предоставляет полезные функции, такие как кэширование производительности и транзакции
В следующих разделах мы рассмотрим настройку и некоторые основные примеры использования.
2. Настройка Maven
Чтобы начать использовать ФОРМУ, нам нужно добавить зависимость reladomo|/в ваш pom.xml файл:
com.goldmansachs.reladomoreladomo16.5.1
Мы будем использовать базу данных H2 для наших примеров, поэтому давайте также добавим зависимость h2 :
com.h2databaseh21.4.196
В дополнение к этому нам нужно настроить плагины, которые будут генерировать классы и файлы SQL и загружать их во время выполнения.
Для генерации файлов мы можем использовать задачи, которые выполняются с помощью maven-antrun-плагина . Во-первых, давайте посмотрим, как мы можем определить задачу для создания классов Java:
Задачаgen-reladomoиспользует предоставленный генераторMithraдля создания файлов Java на основе конфигурации вReladomoClassList.xmlфайл. Мы подробнее рассмотрим, что содержит этот файл, в следующем разделе.
Задачи также имеют два свойства, которые определяют расположение сгенерированных файлов:
generatedDir – содержит классы, которые не должны быть изменены или версированы
nonGeneratedDir – сгенерированные конкретные классы объектов, которые могут быть дополнительно настроены и версированы
Таблицы базы данных, соответствующие объектам Java, могут быть созданы вручную или автоматически с помощью сценариев DDL, сгенерированных второй задачей Ant :
Эта задача использует MithraDbDefinitionGenerator на основе того же ReladomoClassList.xml файл, упомянутый ранее. Сценарии SQL будут помещены в каталог generated-db/sql .
Чтобы завершить определение этого плагина, мы также должны добавить две зависимости, используемые для создания:
Добавление сценариев DDL необязательно. В нашем примере мы будем использовать базу данных в памяти, поэтому мы хотим выполнить сценарии для создания таблиц.
3. Конфигурация XML
Метаданные для фреймворка Reladomo могут быть определены в нескольких XML-файлах.
3.1. Объектные XML-файлы
Каждая сущность, которую мы хотим создать, должна быть определена в своем XML-файле.
Давайте создадим простой пример с двумя сущностями: отделами и сотрудниками. Вот визуальное представление нашей модели предметной области:
Мы можем видеть выше сущность определена внутри корневого элемента, называемогоОбъектом Митры . Затем мы указали пакет, класс и имя соответствующей таблицы базы данных.
Каждое свойство типа определяется с помощью элемента Attribute , для которого мы можем указать имя, тип Java и имя столбца.
Мы можем описать отношения между объектами с помощью тегаRelationship. В нашем примере мы определили отношение один ко многим между объектами Отдел и Сотрудник на основе выражения:
Employee.departmentId = this.id
То имя обратной связи атрибут можно использовать для того, чтобы сделать связь двунаправленной, не определяя ее дважды.
Атрибут related Is Dependent позволяет нам каскадировать операции.
Rella domo нужно рассказать об объектах, которые он должен генерировать.
В разделе Maven мы определили ReladomoClassList.xml файл в качестве источника для задач генерации, поэтому пришло время создать файл:
Это простой файл, содержащий список сущностей, для которых будут созданы классы на основе конфигурации XML.
4. Сгенерированные классы
Теперь у нас есть все элементы, необходимые для начала генерации кода, создав приложение Maven с помощью команды mvn clean install .
Конкретные классы будут сгенерированы в папке src/main/java в указанном пакете:
Это простые классы, в которые мы можем добавить наш пользовательский код. Например, класс Department содержит только конструктор, который не следует удалять:
public class Department extends DepartmentAbstract {
public Department() {
super();
// You must not modify this constructor. Mithra calls this internally.
// You can call this constructor. You can also add new constructors.
}
}
Если мы хотим добавить пользовательский конструктор в этот класс, он также должен вызвать родительский конструктор:
public Department(long id, String name){
super();
this.setId(id);
this.setName(name);
}
Эти классы основаны на абстрактных и служебных классах в папке generated-sources/rella domo :
Основными типами классов в этой папке являются:
DepartmentAbstract и EmployeeAbstract классы – который содержит методы для работы с определенными сущностями
DepartmentListAbstract и EmployeeListAbstract – содержит методы работы со списками отделов и сотрудников
DepartmentFinder и EmployeeFinder – они предоставляют методы для запроса сущностей
другие классы утилит
Генерируя эти классы, большая часть кода, необходимого для выполнения операций CRUD над нашими сущностями, уже создана для нас.
5. Приложение Reladomo
Для выполнения операций с базой данных нам нужен класс диспетчера соединений, который позволяет нам получать соединения с базой данных.
5.1. Диспетчер соединений
При работе с одной базой данных мы можем реализовать интерфейс Source less Connection Manager :
public class ReladomoConnectionManager implements SourcelessConnectionManager {
private static ReladomoConnectionManager instance;
private XAConnectionManager xaConnectionManager;
public static synchronized ReladomoConnectionManager getInstance() {
if (instance == null) {
instance = new ReladomoConnectionManager();
}
return instance;
}
private ReladomoConnectionManager() {
this.createConnectionManager();
}
//...
}
Наш класс Rella domo Connection Manager реализует одноэлементный шаблон и основан на XA Connection Manager , который является служебным классом для менеджера транзакционных соединений.
Давайте подробнее рассмотрим метод createConnectionManager() :
Это, конечно, не обязательно для производственного приложения, где ваши таблицы не будут воссоздаваться для каждого выполнения.
5.2. Инициализация Reladomo
Процесс инициализации Reladomo использует файл конфигурации, который определяет класс диспетчера соединений и используемые типы объектов. Давайте определим/| ReladomoRuntimeConfig.xml файл:
Затем мы можем создать основной класс, в котором сначала вызовем метод createtable () , а затем используем классMithra Managerдля загрузки конфигурации и инициализацииReladomo :
Теперь давайте использовать Reladomo -сгенерированные классы для выполнения нескольких операций над нашими сущностями.
Сначала давайте создадим два объекта Department и Employee , а затем сохраним оба с помощью метода cascade Insert() :
Department department = new Department(1, "IT");
Employee employee = new Employee(1, "John");
department.getEmployees().add(employee);
department.cascadeInsert();
Каждый объект также можно сохранить отдельно, вызвав метод insert () . В нашем примере можно использовать cascade Insert () , потому что мы добавили атрибут relatedIsDependent=true в наше определение отношений.
Для запроса объектов мы можем использовать сгенерированные Искатель занятия:
Department depFound = DepartmentFinder
.findByPrimaryKey(1);
Employee empFound = EmployeeFinder
.findOne(EmployeeFinder.name().eq("John"));
Объекты, полученные таким образом, являются “живыми” объектами, то есть любое изменение в них с помощью сеттеров немедленно отражается в базе данных:
empFound.setName("Steven");
Чтобы избежать такого поведения, мы можем получить отдельные объекты:
Department depDetached = DepartmentFinder
.findByPrimaryKey(1).getDetachedCopy();
Для удаления объектов мы можем использовать метод delete() :
empFound.delete();
5.4. Управление Транзакциями
Если мы хотим, чтобы набор операций выполнялся или не выполнялся как единое целое, мы можем обернуть их в транзакцию:
mithraManager.executeTransactionalCommand(tx -> {
Department dep = new Department(2, "HR");
Employee emp = new Employee(2, "Jim");
dep.getEmployees().add(emp);
dep.cascadeInsert();
return null;
});
6. Поддержка тестирования Reladomo
В приведенных выше разделах мы написали наши примеры в основном классе Java.
Если мы хотим написать тесты для нашего приложения, один из способов сделать это-просто написать тот же код в тестовом классе.
Однако для лучшей поддержки тестов Reladomo также предоставляет классMithraTestResource. Это позволяет нам использовать другую конфигурацию и базу данных в памяти только для тестов.
Во-первых, нам нужно добавить дополнительную зависимость reladomo-test-util вместе с зависимостью junit :