Руководство по Ebean ORM

Руководство по Ebean ORM

1. Вступление

Ebean - инструмент объектно-реляционного сопоставления, написанный на 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 иLogback можно найти на 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.example.ebean.model
transactional-packages: com.example.ebean.app

2.3. логирование

Давайте также создадимlogback.xml и установим уровни ведения журнала для некоторых пакетов наTRACE, чтобы мы могли видеть выполняемые операторы:



3. Настройка сервера

Нам нужно создать экземплярEbeanServer для сохранения сущностей или выполнения запросов к базе данных. Есть два способа, которыми мы можем создать экземпляр сервера - использовать файл свойств по умолчанию или делать это программно.

3.1. Использование файла свойств по умолчанию

Файл свойств по умолчанию может иметь типproperties илиyaml. Ebean будет искать конфигурацию в файлах с именамиapplication.properties,ebean.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. Использование ServerConfig

Затем давайте посмотрим, как мы можем создать один и тот же сервер программно, используяEbeanServerFactory иServerConfig:

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. Экземпляр сервера по умолчанию

A single EbeanServer instance maps to a single database. В зависимости от наших требований мы также можем создать более одного экземпляраEbeanServer.

Если создается только один экземпляр сервера, по умолчанию он регистрируется как экземпляр сервера по умолчанию. Доступ к нему можно получить в любом месте приложения с помощью статического метода классаEbean:

EbeanServer server = Ebean.getDefaultServer();

В случае наличия нескольких баз данных можно зарегистрировать один из экземпляров сервера по умолчанию:

cfg.setDefaultServer(true);

4. Создание сущностей

Ebean обеспечивает полную поддержку аннотаций JPA, а также дополнительных функций с использованием собственных аннотаций.

Давайте создадим несколько сущностей, используя аннотации JPA и Ebean. Сначала мы создадимBaseModel, который содержит свойства, общие для всех сущностей:

@MappedSuperclass
public abstract class BaseModel {

    @Id
    protected long id;

    @Version
    protected long version;

    @WhenCreated
    protected Instant createdOn;

    @WhenModified
    protected Instant modifiedOn;

    // getters and setters
}

Здесь мы использовали аннотацию JPAMappedSuperClass для определенияBaseModel. и двух аннотаций Ebeanio.ebean.annotation.WhenCreated иio.ebean.annotation.WhenModified для целей аудита.

Затем мы создадим две сущностиCustomer иAddress, которые расширяютBaseModel:

@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 мы определили взаимно однозначное сопоставление сAddress и добавили набор каскадных типов вALL, чтобы дочерние сущности также обновлялись вместе с родительскими.

5. Основные операции CRUD

Ранее мы видели, как настроитьEbeanServer и создали две сущности. Теперьlet’s carry out some basic CRUD operations на них.

Мы будем использовать экземпляр сервера по умолчанию для сохранения и доступа к данным. КлассEbean также предоставляет статические методы для сохранения и доступа к данным, которые передают запрос экземпляру сервера по умолчанию:

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() дляEbean, чтобы получить клиента и удалить его с помощьюdelete().

6. Запросы

Query APIs can also be used to create an object graph with filters and predicates. Мы можем использоватьEbean илиEbeanServer для создания и выполнения запросов.

Давайте посмотрим на запрос, который находитCustomer по городу и возвращает sobjectCustomer иAddress только с некоторыми заполненными полями:

Customer customer = Ebean.find(Customer.class)
            .select("name")
            .fetch("address", "city")
            .where()
            .eq("city", "San Jose")
            .findOne();

Здесь с помощьюfind() мы указываем, что хотим найти сущности типаCustomer. Затем мы используемselect(), чтобы указать свойства, которые нужно заполнить в объектеCustomer.

Позже мы используемfetch(), чтобы указать, что мы хотим получить объектAddress, принадлежащийCustomer, и что мы хотим получить полеcity.

Наконец, мы добавляем предикат и ограничиваем размер результата до 1.

7. операции

Ebean по умолчанию выполняет каждый оператор или запрос в новой транзакции.

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

В таких случаях, если мы аннотируем метод с помощьюio.ebean.annotations.Transactional, all, операторы внутри метода будут выполняться внутри одной транзакции:

@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.