1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/hexagonframework-spring-data-ebean

Клонировать/Скачать
README_zh.md 18 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 26.11.2024 23:55 5b08df1

spring-data-ebean

Ebean реализация для spring data.

Build Status Gitter chat

GitHub release

License

MAVEN中央仓库链接

QQ群: 635113788

Spring Data проект основной целью является сделать построение использования DDD репозиториев интерфейсов и реализаций Spring приложений более простым. Этот модуль основан на Ebean ORM (легковесный JPA) репозитории. Используя этот модуль, вы можете использовать преимущества Spring Data в контексте Ebean ORM. Если вы ещё не сталкивались с Spring Data или Ebean ORM, рекомендуется сначала ознакомиться с проектом.

Поддержка некоторых функций

  • Полная поддержка CRUD операций для стандартных сущностей, включая общие запросы
  • Поддержка генерации запросов через аннотации в интерфейсах (ORM запросы, SQL запросы, именованные ORM запросы, именованные SQL запросы, DTO запросы)
  • Поддержка генерации соответствующих запросов через методы в интерфейсах
  • Поддержка QueryChannel сервиса для CQRS
  • Предоставление базовых атрибутов для сущностей и DDD ориентированных классов
  • Встроенная поддержка аудита через аннотации (например, создатель, дата создания, редактор, последняя дата редактирования)
  • Возможность написания собственных запросов на основе Ebean для удобства и гибкости
  • Удобное интегрирование со Spring
  • Поддержка MySQL, Oracle, SQL Server, H2, PostgreSQL и других баз данных

Реализованные сценарии

  1. Получение отдельной сущности по первичному ключу
  2. Получение списка сущностей по условию
  3. Сохранение новой отдельной сущности и возврат первичного ключа
  4. Пакетное сохранение нескольких одинаковых сущностей и возвращение списка первичных ключей
  5. Обновление существующей сущности — одновременное обновление всех полей сущности
  6. Получение отношения «многие к одному» (отдел принадлежит компании)
  7. Получение отношения «один ко многим» (компании принадлежат отделы)
  8. Обновление отношения «один ко многим» для сущности (компания владеет отделами) — добавление двух проектов, обновление двух проектов и удаление одного проекта — всё это с помощью одной строки кода/операции
  9. Сложный выбор — создание условий выбора на основе логических условий и соединений
  10. Выполнение запроса с использованием JDBC простых операторов (не PreparedStatement)
  11. Удаление отдельной сущности по первичному ключу

Почему выбрать Ebean ORM

Легковесная реализация JPA ORM с поддержкой ассоциаций сущностей, которые не поддерживаются Mybatis, но с гибкостью запросов, подобной Mybatis. Для реализации требований к репозиториям агрегатных корней в моделях предметной области (сохранение агрегатного корня одновременно сохраняет связанные сущности и значения), а также partial objects, Ebean подходит идеально.

Я выбираю реляционную систему сохранения данных на основе следующих принципов:

  1. Предпочтение SQL вместо скрытия
  2. Возможность реализации модели предметной области
  3. Возможность использования JPA аннотаций, но не полной реализации JPA (здесь я склоняюсь к Ebean)
  4. Достаточная зрелость для удовлетворения потребностей корпоративных приложений (Ebean и Hibernate были созданы в одно время и продолжают обновляться для удовлетворения более высоких требований)

Сравнение фреймворков

Ссылка: java-persistence-frameworks-comparison

Hibernate/JPA

  • Сравнить с JPA
  • В любом случае лучше, чем Hibernate/JPA

JDBC Template

  • Преимущества
    • Чувствую себя очень близко к JDBC
    • Реализованы все сценарии без больших проблем — нет скрытых сюрпризов
    • Очень легко выполнять пакетные операции
    • Простота настройки
  • Недостатки
    • При использовании встроенного SQL в Java код читаемость репозиториев ухудшается. Если бы Java поддерживал многострочные строки, было бы лучше
    • Улучшение ведения журнала отладки

jOOQ

  • Преимущества
    • Очень плавный, легко писать новые запросы, код очень читаемый
    • После настройки очень просто в использовании, идеально подходит для простых запросов
    • Отличный регистратор отладки вывода
  • Недостатки
    • Некоторые лицензии на базы данных — трудно убедить менеджеров, что это того стоит :)
    • Для больших запросов не так много пользы — лучше использовать собственный SQL (см. сценарий 9)
    • Странный синтаксис для пакетных операций (если вы не используете UpdatableRecord). Но это не так уж плохо...

MyBatis

  • Преимущества
    • Написание SQL-запросов в XML файлах отображения очень приятно
  • Недостатки
    • Создание DAO и репозиториев требует написания множества файлов (DAO/Repository, XXXMapper, XXXMapper.xml), методы становятся громоздкими
    • Невозможно выполнять пакетную обработку в одном методе, невозможно каскадное заполнение
    • Даже простые CRUD операции кажутся громоздкими, приводя к существованию различных сторонних фреймворков, компенсирующих недостатки MyBatis
    • Невозможность объектно-ориентированного подхода, невозможность реализации DDD

EBean

  • Преимущества
    • Все сценарии реализованы идеально, высокая читаемость кода
    • Реализация пакетной обработки очень проста
    • ORM запросы, SQL запросы и DTO запросы очень просты
  • Недостатки
    • Функция DTO запросов новая, требуется дополнительная поддержка XML mapping для DTO

    • Необходимо «усиливать» сущности, хотя на самом деле это касается только настройки среды (IDE плагин и Gradle плагин), после чего можно забыть об этом. ``` result2.size()); assertEquals("Yuan", result2.get(0).getLastname()); assertThat(result2, hasItem(user));

      List<User> result3 = repository.findUsersByLastnameEquals("Yuan");
      assertEquals(1, result3.size());
      assertEquals("Yuan", result3.get(0).getLastname());
      
      User result4 = repository.findUserByEmailAddressEqualsOql("yuanxuegui@163.com");
      assertEquals("yuanxuegui@163.com", result4.getEmailAddress());
      
      User result5 = repository.findUserByEmailAddress("yuanxuegui@163.com");
      assertEquals("yuanxuegui@163.com", result5.getEmailAddress());
      
      int result6 = repository.changeUserEmailAddress("yuanxuegui@163.com", "yuanxuegui@126.com");
      assertEquals(1, result6);
      
      List<User> result7  = repository.findByLastnameOql("Yuan");
      assertEquals("yuanxuegui@126.com", result7.get(0).getEmailAddress());
      
      int result8 = repository.deleteUserByEmailAddress("yuanxuegui@126.com");
      assertEquals(1, result8);
      
      User result9 = repository.findUserByEmailAddress("yuanxuegui@126.com");
      assertNull(result9);
      
      user = new User("Xuegui", "Yuan", "yuanxuegui@163.com");
      user.setAge(29);
      user = repository.save(user);
      
      User result10 = repository.findUserByEmailAddress("yuanxuegui@163.com");
      assertNotNull(result10);
      
      int result11 = repository.deleteUserByEmailAddressOql("yuanxuegui@163.com");
      assertEquals(1, result11);
      
      User result12 = repository.findUserByEmailAddress("yuanxuegui@163.com");
      assertNull(result12);

      } @Test public void testFindByExample() { User u = new User(); u.setEmailAddress("YUANXUEGUI"); List result1 = repository.findAll(Example.of(u, ExampleMatcher.matchingAll() .withIgnoreCase(true) .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING))); assertEquals(1, result1.size()); assertEquals("Yuan", result1.get(0).getLastname()); assertThat(result1, hasItem(user));

      List<User> result2 = repository.findAll(Example.of(u, ExampleMatcher.matchingAll()
              .withIgnoreCase(false)
              .withStringMatcher(ExampleMatcher.StringMatcher.EXACT)));
      assertEquals(0, result2.size());

      } }


@Data @IncludeFields("emailAddress,fullName(lastName,firstName),age") public class UserQuery { @ExprParam(expr = ExprType.CONTAINS) private String emailAddress;

@ExprParam(name = "age", expr = ExprType.GE)
private int ageStart;

@ExprParam(name = "age", expr = ExprType.LE)
private int ageEnd;

}


package org.springframework.data.ebean.querychannel;

import io.ebean.Query; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.ebean.sample.config.SampleConfig; import org.springframework.data.ebean.sample.domain.User; import org.springframework.data.ebean.sample.domain.UserInfo; import org.springframework.data.ebean.sample.domain.UserRepository; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.HashMap; import java.util.Map;

import static org.junit.Assert.assertEquals;

/**

  • @author Xuegui Yuan */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SampleConfig.class) public class EbeanQueryChannelServiceIntegrationTests { // Test fixture User user; @Autowired private EbeanQueryChannelService ebeanQueryChannelService; @Autowired private UserRepository repository;

    @Before public void initUser() { repository.deleteAll(); user = new User("QueryChannel", "Test", "testquerychannel@163.com"); user.setAge(29); user = repository.save(user); }

String sql1 = "select first_name, last_name, email_address from user where last_name= :lastName";
    String sql2 = "select first_name as firstName, last_name as lastName, email_address as emailAddress from user where last_name= :lastName";
    Map<String, String> columnsMapping = new HashMap<>();
    columnsMapping.put("first_name", "firstName");
    columnsMapping.put("last_name", "lastName");

    Query<UserInfo> query1 = ebeanQueryChannelService.createSqlQuery(UserInfo.class,
            sql1);
    Query<UserInfo> query2 = ebeanQueryChannelService.createSqlQuery(UserInfo.class,
            sql2);
    Query<UserInfo> query3 = ebeanQueryChannelService.createSqlQueryMappingColumns(UserInfo.class,
            sql1, columnsMapping);

    query1.setParameter("lastName", "Test");
    query2.setParameter("lastName", "Test");
    query3.setParameter("lastName", "Test");
    UserInfo userInfo1 = query1.findOne();
    UserInfo userInfo2 = query2.findOne();
    UserInfo userInfo3 = query3.findOne();
    assertEquals("QueryChannel", userInfo1.getFirstName());
    assertEquals("testquerychannel@163.com", userInfo1.getEmailAddress());
    assertEquals("QueryChannel", userInfo2.getFirstName());
    assertEquals("testquerychannel@163.com", userInfo2.getEmailAddress());
    assertEquals("QueryChannel", userInfo3.getFirstName());
    assertEquals("testquerychannel@163.com", userInfo3.getEmailAddress());
}

@Test
public void createNamedQuery() {
    UserInfo userInfo = ebeanQueryChannelService.createNamedQuery(UserInfo.class,
            "userInfoByEmail").setParameter("emailAddress",
            "testquerychannel@163.com").findOne();
    assertEquals("QueryChannel", userInfo.getFirstName());
    assertEquals("testquerychannel@163.com", userInfo.getEmailAddress());
}

@Test
public void createNamedQueryWhere() {
    UserInfo userInfo = ebeanQueryChannelService.createNamedQuery(UserInfo.class,
            "userInfo").where()
            .eq("emailAddress", "testquerychannel@163.com").findOne();
    assertEquals("QueryChannel", userInfo.getFirstName());
    assertEquals("testquerychannel@163.com", userInfo.getEmailAddress());
}

@Test
public void createDtoQuery() {
    String sql = "select first_name, last_name, email_address from user where email_address = :emailAddress";
    UserDTO userDTO = ebeanQueryChannelService.createDtoQuery(UserDTO.class, sql)
            .setParameter("emailAddress", "testquerychannel@163.com")
            .findOne();
    assertEquals("QueryChannel", userDTO.getFirstName());
    assertEquals("testquerychannel@163.com", userDTO.getEmailAddress());
}

@Test
public void query_queryObject() {
    UserQuery userQuery = new UserQuery();
    userQuery.setEmailAddress("testquerychannel@163.com");
    userQuery.setAgeStart(1);
    userQuery.setAgeEnd(30);
    UserDTO user = queryChannel.createQuery(User.class, userQuery)
            .asDto(UserDTO.class)
            .setRelaxedMode()
            .findOne();
    assertEquals("testquerychannel@163.com", user.getEmailAddress());
}

@Test
public void applyQueryObject() {
    UserQuery userQuery = new UserQuery();
    userQuery.setEmailAddress("testquerychannel@163.com");
    userQuery.setAgeStart(1);
    userQuery.setAgeEnd(30);
    UserInfo userInfo = EbeanQueryChannelService.applyWhere(queryChannel.createNamedQuery(UserInfo.class,
            "userInfo").where(), userQuery).findOne();
    assertEquals("QueryChannel", userInfo.getFirstName());
    assertEquals("testquerychannel@163.com", userInfo.getEmailAddress());
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/hexagonframework-spring-data-ebean.git
git@api.gitlife.ru:oschina-mirror/hexagonframework-spring-data-ebean.git
oschina-mirror
hexagonframework-spring-data-ebean
hexagonframework-spring-data-ebean
master