Статьи

Начало работы с jOOQ, H2 и Maven

Эта статья является частью нашего академического курса под названием jOOQ — тип безопасного запроса в БД .

jOOQ — хороший выбор в приложении Java, где важны SQL и конкретная реляционная база данных. Это альтернатива, когда JPA / Hibernate слишком много абстрагирует, JDBC слишком мало. Он показывает, как современный предметно-ориентированный язык может значительно повысить производительность труда разработчиков, внедряя SQL в Java.

В этом курсе мы увидим, как мы можем эффективно запрашивать базы данных, используя jOOQ. Проверьте это здесь !

1. Настройка курсового проекта

В этом разделе мы узнаем, как правильно настроить проект курса, который вы можете получить здесь: https://github.com/jOOQ/jOOQ/tree/master/jOOQ-examples/jOOQ-academy .

Чтобы запустить примеры этого курса непосредственно из GitHub, вам необходимо установить:

Если у вас уже установлена ​​ваша любимая IDE (например, Eclipse, IntelliJ или NetBeans), вы можете легко импортировать проект jOOQ Academy Maven непосредственно из GitHub. Все, что вам нужно сделать, чтобы установить базу данных и запустить генератор кода jOOQ, это вызвать:

1
mvn clean install

2. Пример базы данных H2

Весь курс будет выполнять запросы к простой примерной базе данных H2, исходный код которой можно получить здесь: https://github.com/jOOQ/jOOQ/blob/master/jOOQ-examples/jOOQ-academy/src/main/ ресурсы / дб-h2.sql

Вам не нужно ничего устанавливать вручную. Пример базы данных устанавливается автоматически при сборке проекта jOOQ Academy Maven с Maven. Для справки, мы воспроизведем базу данных здесь:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
DROP TABLE IF EXISTS book_to_book_store
;
DROP TABLE IF EXISTS book_store
;
DROP TABLE IF EXISTS book
;
DROP TABLE IF EXISTS author
;
 
DROP SEQUENCE IF EXISTS s_author_id
;
CREATE SEQUENCE s_author_id START WITH 1
;
 
CREATE TABLE author (
  id INT NOT NULL,
  first_name VARCHAR(50),
  last_name VARCHAR(50) NOT NULL,
  date_of_birth DATE,
 
  CONSTRAINT pk_t_author PRIMARY KEY (ID)
)
;
 
CREATE TABLE book (
  id INT NOT NULL,
  author_id INT NOT NULL,
  title VARCHAR(400) NOT NULL,
  published_in INT,
 
  rec_timestamp TIMESTAMP,
 
  CONSTRAINT pk_t_book PRIMARY KEY (id),
  CONSTRAINT fk_t_book_author_id FOREIGN KEY (author_id) REFERENCES author(id),
)
;
 
CREATE TABLE book_store (
  name VARCHAR(400) NOT NULL,
 
  CONSTRAINT uk_t_book_store_name PRIMARY KEY(name)
)
;
 
CREATE TABLE book_to_book_store (
  book_store_name VARCHAR(400) NOT NULL,
  book_id INTEGER NOT NULL,
  stock INTEGER,
 
  CONSTRAINT pk_b2bs PRIMARY KEY(book_store_name, book_id),
  CONSTRAINT fk_b2bs_bs_name FOREIGN KEY (book_store_name)
                             REFERENCES book_store (name)
                             ON DELETE CASCADE,
  CONSTRAINT fk_b2bs_b_id    FOREIGN KEY (book_id)
                             REFERENCES book (id)
                             ON DELETE CASCADE
)
;
 
INSERT INTO author VALUES (next value for s_author_id, 'George', 'Orwell', '1903-06-25')
;
INSERT INTO author VALUES (next value for s_author_id, 'Paulo', 'Coelho', '1947-08-24')
;
 
INSERT INTO book VALUES (1, 1, '1984'        , 1948, null)
;
INSERT INTO book VALUES (2, 1, 'Animal Farm' , 1945, null)
;
INSERT INTO book VALUES (3, 2, 'O Alquimista', 1988, null)
;
INSERT INTO book VALUES (4, 2, 'Brida'       , 1990, null)
;
 
INSERT INTO book_store (name) VALUES
    ('Amazon'),
    ('Barnes and Noble'),
    ('Payot')
;
 
INSERT INTO book_to_book_store VALUES
    ('Amazon', 1, 10),
    ('Amazon', 2, 10),
    ('Amazon', 3, 10),
    ('Barnes and Noble', 1, 1),
    ('Barnes and Noble', 3, 2),
    ('Payot', 3, 1)
;
 
DROP ALIAS IF EXISTS count_books
;
 
CREATE OR REPLACE ALIAS count_books AS $$
int countBooks(Connection c, int authorID) throws SQLException {
    try (PreparedStatement s = c.prepareStatement("SELECT COUNT(*) FROM book WHERE author_id = ?")) {
        s.setInt(1, authorID);
 
        try (ResultSet rs = s.executeQuery()) {
            rs.next();
            return rs.getInt(1);
        }
    }
}
$$
;

Как видите, мы используем очень распространенные функции SQL:

  • Таблицы с первичными ключами и внешними ключами
  • Последовательности для генерации идентификатора
  • Хранимые процедуры

3. Генератор кода

jOOQ генерирует код Java из метаинформации вашей базы данных. Это означает, что приведенная выше схема будет создавать классы для каждой из приведенных выше таблиц, которые выглядят примерно так:

Класс, содержащий статические ссылки на все таблицы

1
2
3
4
5
6
public class Tables {
    public static final Author          AUTHOR             = // [...]
    public static final Book            BOOK               = // [...]
    public static final BookStore       BOOK_STORE         = // [...]
    public static final BookToBookStore BOOK_TO_BOOK_STORE = // [...]
}

Каждая таблица имеет ссылки на все свои столбцы

1
2
3
4
5
6
public class Author extends TableImpl<AuthorRecord> {
    public final TableField<AuthorRecord, Integer>   ID            = // [...]
    public final TableField<AuthorRecord, String>    FIRST_NAME    = // [...]
    public final TableField<AuthorRecord, String>    LAST_NAME     = // [...]
    public final TableField<AuthorRecord, Timestamp> DATE_OF_BIRTH = // [...]
}

Это самые важные генерируемые артефакты. Мы рассмотрим сгенерированные записи, POJO, DAO, а также сгенерированные объекты для последовательностей и хранимых процедур позже.