1. введение
Эбеан это инструмент объектно-реляционного отображения, написанный на Java.
Он поддерживает стандартные аннотации JPA для объявления сущностей. Тем не менее, он предоставляет гораздо более простой API для сохранения. На самом деле, один из моментов, заслуживающих упоминания об архитектуре Ebean, заключается в том, что она не имеет сеанса, что означает, что она не полностью управляет сущностями.
Кроме того, он также поставляется с API запросов и поддерживает написание запросов на собственном SQL. Ebean поддерживает все основные поставщики баз данных, такие как Oracle, Postgres, MySQL, H2 и т.д.
В этом уроке мы рассмотрим, как мы можем создавать, сохранять и запрашивать сущности с помощью Ebean и H2.
2. Настройка
Для начала давайте рассмотрим наши зависимости, а также некоторые базовые настройки.
2.1. Зависимости Maven
Прежде чем мы начнем, давайте импортируем необходимые зависимости:
io.ebean ebean 11.22.4 com.h2database h2 1.4.196 ch.qos.logback logback-classic 1.2.3
Последние версии Ebean , H2 и Log back можно найти на Maven Central.
2.2. Усовершенствования
Ebean необходимо изменить компоненты сущностей, чтобы ими мог управлять сервер. Таким образом, мы добавим плагин Maven для выполнения этой работы:
io.ebean ebean-maven-plugin 11.11.2 main process-classes debug=1 enhance
Нам также необходимо предоставить плагину Maven имена пакетов, содержащих сущности и классы, которые используют транзакции. Для этого мы создаем файл ebean.mf:
entity-packages: com.baeldung.ebean.model transactional-packages: com.baeldung.ebean.app
2.3. Ведение журнала
Давайте также создадим logback.xml и установите уровни ведения журнала в некоторых пакетах на TRACE , чтобы мы могли видеть выполняемые операторы:
3. Настройка сервера
Нам нужно создать экземпляр EbeanServer для сохранения сущностей или выполнения запросов к базе данных. Существует два способа создания экземпляра сервера – с помощью файла свойств по умолчанию или программно.
3.1. Использование файла свойств по умолчанию
Файл свойств по умолчанию может иметь тип properties или yaml . Ebean будет искать конфигурацию в файлах с именами application.properties , bean.properties или application.yml .
Помимо предоставления сведений о подключении к базе данных, мы также можем поручить Ebean создавать и запускать операторы DDL.
Теперь давайте рассмотрим пример конфигурации:
ebean.db.ddl.generate=true ebean.db.ddl.run=true datasource.db.username=sa datasource.db.password= datasource.db.databaseUrl=jdbc:h2:mem:customer datasource.db.databaseDriver=org.h2.Driver
3.2. Использование конфигурации сервера
Далее давайте рассмотрим, как мы можем создать один и тот же сервер программно, используя EbeanServerFactory и Server Config :
ServerConfig cfg = new ServerConfig(); Properties properties = new Properties(); properties.put("ebean.db.ddl.generate", "true"); properties.put("ebean.db.ddl.run", "true"); properties.put("datasource.db.username", "sa"); properties.put("datasource.db.password", ""); properties.put("datasource.db.databaseUrl","jdbc:h2:mem:app2"; properties.put("datasource.db.databaseDriver", "org.h2.Driver"); cfg.loadFromProperties(properties); EbeanServer server = EbeanServerFactory.create(cfg);
3.3. Экземпляр сервера по умолчанию
Один экземпляр EbeanServer сопоставляется с одной базой данных. В зависимости от наших требований мы также можем создать несколько экземпляров EbeanServer .
Если создается только один экземпляр сервера, по умолчанию он регистрируется как экземпляр сервера по умолчанию. К нему можно получить доступ в любом месте приложения, используя статический метод в классе Ebean :
EbeanServer server = Ebean.getDefaultServer();
В случае наличия нескольких баз данных можно зарегистрировать один из экземпляров сервера в качестве экземпляра по умолчанию:
cfg.setDefaultServer(true);
4. Создание сущностей
Ebean обеспечивает полную поддержку аннотаций JPA, а также дополнительные функции с использованием собственных аннотаций.
Давайте создадим несколько сущностей, используя аннотации JPA и Bean. Во-первых, мы создадим Базовую модель , которая содержит свойства, общие для всех сущностей :
@MappedSuperclass public abstract class BaseModel { @Id protected long id; @Version protected long version; @WhenCreated protected Instant createdOn; @WhenModified protected Instant modifiedOn; // getters and setters }
Здесь мы использовали аннотацию MappedSuperclass JPA для определения базовой модели|/. И две аннотации Ebean io.ebean.annotation.При создании и io.ebean.аннотации.При изменении в целях аудита.
Далее мы создадим две сущности Клиент и Адрес , которые расширяют Базовую модель :
@Entity public class Customer extends BaseModel { public Customer(String name, Address address) { super(); this.name = name; this.address = address; } private String name; @OneToOne(cascade = CascadeType.ALL) Address address; // getters and setters }
@Entity public class Address extends BaseModel{ public Address(String addressLine1, String addressLine2, String city) { super(); this.addressLine1 = addressLine1; this.addressLine2 = addressLine2; this.city = city; } private String addressLine1; private String addressLine2; private String city; // getters and setters }
В Customer мы определили взаимно однозначное сопоставление с Адресом и добавили set cascadetype в ALL , чтобы дочерние сущности также обновлялись вместе с родительскими сущностями.
5. Основные операции CRUD
Ранее мы видели, как настроить EbeanServer и создали две сущности. Теперь, давайте выполним некоторые основные операции CRUD на них.
Мы будем использовать экземпляр сервера по умолчанию для сохранения и доступа к данным. Класс Bean также предоставляет статические методы для сохранения и доступа к данным, которые перенаправляют запрос на экземпляр сервера по умолчанию:
Address a1 = new Address("5, Wide Street", null, "New York"); Customer c1 = new Customer("John Wide", a1); EbeanServer server = Ebean.getDefaultServer(); server.save(c1); c1.setName("Jane Wide"); c1.setAddress(null); server.save(c1); Customer foundC1 = Ebean.find(Customer.class, c1.getId()); Ebean.delete(foundC1);
Сначала мы создаем объект Customer и используем экземпляр сервера по умолчанию, чтобы сохранить его с помощью save() .
Затем мы обновляем данные клиента и снова сохраняем их с помощью save() .
Наконец, мы используем статический метод find() on Ebean для извлечения клиента и удаления его с помощью delete() .
6. Запросы
API запросов также можно использовать для создания графа объектов с фильтрами и предикатами. Мы можем использовать Ebean или EbeanServer для создания и выполнения запросов.
Давайте рассмотрим запрос, который находит Клиента по городу и возвращает Клиента и Адрес объект с заполненными только некоторыми полями:
Customer customer = Ebean.find(Customer.class) .select("name") .fetch("address", "city") .where() .eq("city", "San Jose") .findOne();
Здесь с помощью find() мы указываем, что хотим найти объекты типа Customer . Затем мы используем select () , чтобы указать свойства для заполнения в объекте Customer .
Позже мы используем fetch () , чтобы указать, что мы хотим получить Адрес объект, принадлежащий Клиенту , и что мы хотим получить город поле .
Наконец, мы добавляем предикат и ограничиваем размер результата 1.
7. Сделки
Ebean по умолчанию выполняет каждую инструкцию или запрос в новой транзакции.
Хотя в некоторых случаях это может не быть проблемой. Бывают случаи, когда мы можем захотеть выполнить набор инструкций в рамках одной транзакции.
В таких случаях, если мы аннотируем метод с помощью io.ebean.annotations.Транзакционный, все операторы в методе будут выполняться внутри одной транзакции:
@Transactional public static void insertAndDeleteInsideTransaction() { Customer c1 = getCustomer(); EbeanServer server = Ebean.getDefaultServer(); server.save(c1); Customer foundC1 = server.find(Customer.class, c1.getId()); server.delete(foundC1); }
8. Построение проекта
Наконец, мы можем построить проект Maven с помощью команды:
compile io.ebean:ebean-maven-plugin:enhance
9. Заключение
Подводя итог, мы рассмотрели основные функции Ebean, которые можно использовать для сохранения и запроса сущностей в реляционной базе данных.
Наконец, этот код доступен на Github .