jOOQ — это внутренний DSL и генератор исходного кода, моделирующий язык SQL как типобезопасный Java API для помощи в написании более качественного SQL.
Основные возможности включают:
Дополнительные возможности включают:
MULTISET
и ROW
вложенные коллекции и записиjOOQ основной функцией является безопасный, встроенный SQL, позволяющий использовать автозавершение IDE для синтаксиса SQL...
... а также для метаданных схемы:
Это позволяет предотвратить ошибки различных типов, в том числе опечатки идентификаторов:
Или несоответствие типов данных:
Примеры взяты из блоговой статьи о генерации кода.
Для большего количества примеров, пожалуйста, обратитесь к демонстрационному проекту. Один из ключевых примеров, показывающих различные силы jOOQ, представлен в блоговой статье о новом операторе MULTISET
.
Учитывая эти целевые DTO:
record Actor(String firstName, String lastName) {}
record Film(
String title,
List<Actor> actors,
List<String> categories
) {}
Вы можете теперь написать следующий запрос для получения фильмов, их вложенных актёров и их вложенных категорий в одном типобезопасном запросе:
List<Film> result =
dsl.select(
FILM.TITLE,
multiset(
select(
FILM.actor().FIRST_NAME,
FILM.actor().LAST_NAME)
.from(FILM.actor())
).as("actors").convertFrom(r -> r.map(mapping(Actor::new))),
multiset(
select(FILM.category().NAME)
.from(FILM.category())
).as("categories").convertFrom(r -> r.map(Record1::value1))
)
.from(FILM)
.orderBy(FILM.TITLE)
.fetch(mapping(Film::new));
Запрос полностью типобезопасен. Измените тип столбца, имя или целевой DTO, и он перестанет компилироваться! Верьте только своим глазам:
А здесь вы видите работу вложенных результатов из логов:
Как это работает? Посмотрите на этот аннотированный пример:
List<Film> result =
dsl.select(
FILM.TITLE,
// MULTISET — это стандартный SQL-оператор, который позволяет вкладывать коллекции непосредственно в SQL. Он либо
// - поддерживается нативно
// - эмулируется с помощью SQL/JSON или SQL/XML
multiset(
// Неявные соединения на основе путей позволяют упрощать навигацию по внешним ключам.
select(
FILM.actor().FIRST_NAME,
FILM.actor().LAST_NAME)
// Неявная корреляция с внешними запросами позволяет избежать повторного написания предикатов.
.from(FILM.actor())
// Временная конвертация позволяет маппировать структурные типы Record2<String, String> к вашему пользовательскому DTO с помощью ссылок на конструкторы
).as("actors").convertFrom(r -> r.map(mapping(Actor::new))),
multiset(
select(FILM.category().NAME)
.from(FILM.category())
).as("categories").convertFrom(r -> r.map(Record1::value1))
)
.from(FILM)
.orderBy(FILM.TITLE)
.fetch(mapping(Film::new));
Сгенерированный SQL-запрос может выглядеть так, например, в PostgreSQL:```sql SELECT film.title, ( SELECT COALESCE( JSONB_AGG(JSONB_BUILD_OBJECT( 'first_name', t.first_name, 'last_name', t.last_name )), JSONB_BUILD_ARRAY() ) FROM ( SELECT alias_78509018.first_name, alias_78509018.last_name FROM ( film_actor JOIN actor AS alias_78509018 ON film_actor.actor_id = alias_78509018.actor_id ) WHERE film_actor.film_id = film.film_id ) AS t ) AS actors, ( SELECT COALESCE( JSONB_AGG(JSONB_BUILD_OBJECT('name', t.name)), JSONB_BUILD_ARRAY() ) FROM ( SELECT alias_130639425.name FROM ( film_category JOIN category AS alias_130639425 ON film_category.category_id = alias_130639425.category_id ) WHERE film_category.film_id = film.film_id ) AS t ) AS categories FROM film ORDER BY film.title
Этот конкретный пример подробнее объясняется в блоговой статье о новом операторе `MULTISET`. Для большего количества примеров, [пожалуйста, обратитесь к демонстрационному проекту](https://github.com/jOOQ/demo).
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )