1. 소개

이 예제에서는 jOOQ (Java Object Orientated Query)를 사용 하여 애플리케이션을 실행하는 방법을 간략히 살펴보겠습니다 . 이 라이브러리는 데이터베이스 테이블을 기반으로 Java 클래스를 생성하고 유창한 API를 통해 유형 안전 SQL 쿼리를 생성할 수 있도록 합니다.

전체 설정, PostgreSQL 데이터베이스 연결 및 CRUD 작업의 몇 가지 예를 다룰 것입니다.

2. 메이븐 의존성

jOOQ 라이브러리의 경우 다음 세 가지 jOOQ 의존성 이 필요합니다 .

<dependency>
    <groupId>org.jooq</groupId>
    <artifactId>jooq</artifactId>
    <version>3.13.4</version>
</dependency>
<dependency>
    <groupId>org.jooq</groupId>
    <artifactId>jooq-meta</artifactId>
    <version>3.13.4</version>
</dependency>
<dependency>
    <groupId>org.jooq</groupId>
    <artifactId>jooq-codegen</artifactId>
    <version>3.13.4</version>
</dependency>

PostgreSQL 드라이버에 대한 의존성도 하나 필요 합니다 .

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.2.16</version>
</dependency>

3. 데이터베이스 구조

시작하기 전에 예제를 위한 간단한 DB 스키마를 생성해 보겠습니다. 간단한 AuthorArticle 관계를 사용합니다.

create table AUTHOR
(
    ID         integer PRIMARY KEY,
    FIRST_NAME varchar(255),
    LAST_NAME  varchar(255),
    AGE        integer
);

create table ARTICLE
(
    ID          integer PRIMARY KEY,
    TITLE       varchar(255) not null,
    DESCRIPTION varchar(255),
    AUTHOR_ID   integer
        CONSTRAINT fk_author_id REFERENCES AUTHOR
);

4. 데이터베이스 연결

이제 데이터베이스에 연결 하는 방법을 살펴보겠습니다 .

먼저 사용자, 암호 및 데이터베이스에 대한 전체 URL을 제공해야 합니다. 이러한 속성을 사용하여 DriverManager 및 해당 getConnection 메서드를 사용하여 연결 개체 를 만듭니다 .

String userName = "user";
String password = "pass";
String url = "jdbc:postgresql://db_host:5432/baeldung";
Connection conn = DriverManager.getConnection(url, userName, password);

다음으로 DSLContext 의 인스턴스를 생성해야 합니다 . 이 객체는 jOOQ 인터페이스의 진입점이 될 것입니다.

DSLContext context = DSL.using(conn, SQLDialect.POSTGRES);

우리의 경우에는 POSTGRES 방언을 전달 하지만 H2, MySQL, SQLite 등과 같이 사용할 수 있는 방언은 거의 없습니다.

5. 코드 생성

데이터베이스 테이블에 대한 Java 클래스를 생성하려면 다음 jooq-config.xml 파일 이 필요 합니다.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration xmlns="http://www.jooq.org/xsd/jooq-codegen-3.13.0.xsd">
    
    <jdbc>
        <driver>org.postgresql.Driver</driver>
        <url>jdbc:postgresql://db_url:5432/baeldung_database</url>
        <user>username</user>
        <password>password</password>
    </jdbc>

    <generator>
        <name>org.jooq.codegen.JavaGenerator</name>

        <database>
            <name>org.jooq.meta.postgres.PostgresDatabase</name>
            <inputSchema>public</inputSchema>
            <includes>.*</includes>
            <excludes></excludes>
        </database>

        <target>
            <packageName>com.baeldung.jooq.model</packageName>
            <directory>C:/projects/baeldung/tutorials/jooq-examples/src/main/java</directory>
        </target>
    </generator>
</configuration>

사용자 지정 구성을 사용하려면 데이터베이스 자격 증명을 배치 하는 <jdbc> 섹션 과 생성할 클래스의 패키지 이름 및 위치 디렉토리를 구성하는 <target> 섹션을 변경해야 합니다.

jOOQ 코드 생성 도구를 실행하려면 다음 코드를 실행해야 합니다.

GenerationTool.generate(
  Files.readString(
    Path.of("jooq-config.xml")
  )    
);

생성이 완료되면 각각 데이터베이스 테이블에 해당하는 두 개의 다음 클래스를 얻게 됩니다.

com.baeldung.model.generated.tables.Article;
com.baeldung.model.generated.tables.Author;

6. CRUD 작업

이제 jOOQ 라이브러리로 수행할 수 있는 몇 가지 기본 CRUD 작업을 살펴보겠습니다.

6.1. 만들기

먼저 새 Article 레코드를 생성해 보겠습니다 . 그렇게 하려면 적절한 테이블 참조를 매개변수로 사용 하여 newRecord 메서드 를 호출해야 합니다 .

ArticleRecord article = context.newRecord(Article.ARTICLE);

Article.ARTICLE의 변수에 대한 참조 인스턴스 문서의 데이터베이스 테이블. 코드 생성 중에 jOOQ에 의해 자동으로 생성되었습니다.

다음으로 필요한 모든 속성에 대한 값을 설정할 수 있습니다.

article.setId(2);
article.setTitle("jOOQ examples");
article.setDescription("A few examples of jOOQ CRUD operations");
article.setAuthorId(1);

마지막으로 데이터베이스에 저장하기 위해 레코드에 대한 store 메소드 를 호출해야 합니다.

article.store();

6.2. 독서

이제 데이터베이스에서 값을 읽는 방법을 살펴보겠습니다. 예를 들어 모든 작성자를 선택하겠습니다.

Result<Record> authors = context.select()
  .from(Author.AUTHOR)
  .fetch();

여기에서 우리가 읽고 싶은 테이블을 나타내기 위해 from과 결합된 select 메소드를 사용하고 있습니다. fetch 메서드를 호출하면 SQL 쿼리가 실행되고 생성된 결과가 반환됩니다.

결과 객체 구현 의 Iterable 인터페이스는, 그래서 각각의 요소를 통해 쉽게 반복 할 수 있습니다. 단일 레코드에 액세스하는 동안 적절한 필드 참조와 함께 getValue 메서드를 사용하여 해당 매개변수를 가져올 수 있습니다 .

authors.forEach(author -> {
    Integer id = author.getValue(Author.AUTHOR.ID);
    String firstName = author.getValue(Author.AUTHOR.FIRST_NAME);
    String lastName = author.getValue(Author.AUTHOR.LAST_NAME);
    Integer age = author.getValue(Author.AUTHOR.AGE);

    System.out.printf("Author %s %s has id: %d and age: %d%n", firstName, lastName, id, age);
});

선택 쿼리를 특정 필드 집합으로 제한할 수 있습니다. 기사 ID와 제목만 가져오자:

Result<Record2<Integer, String>> articles = context.select(Article.ARTICLE.ID, Article.ARTICLE.TITLE)
  .from(Author.AUTHOR)
  .fetch();

fetchOne 메소드를 사용하여 단일 객체를 선택할 수도 있습니다 . 이 매개변수는 테이블 참조 및 적절한 레코드와 일치하는 조건입니다.

우리의 경우 id가 1인 Author선택합시다 .

AuthorRecord author = context.fetchOne(Author.AUTHOR, Author.AUTHOR.ID.eq(1))

조건과 일치하는 레코드가 없으면 fetchOne 메서드는 null 을 반환 합니다.

6.3. 업데이트 중

주어진 레코드를 업데이트하려면 변경해야 하는 모든 필드에 대한 set 메서드 호출 과 결합된 DSLContext 개체 업데이트 메서드를 사용할 수 있습니다. 이 문 다음에 적절한 일치 조건이 있는 where 절이 와야 합니다.

context.update(Author.AUTHOR)
  .set(Author.AUTHOR.FIRST_NAME, "David")
  .set(Author.AUTHOR.LAST_NAME, "Brown")
  .where(Author.AUTHOR.ID.eq(1))
  .execute();

업데이트 쿼리는 실행 메서드를 호출한 후에만 실행됩니다 . 반환 값으로 업데이트된 레코드 수와 동일한 정수를 얻습니다.

저장 메소드 를 실행하여 이미 가져온 레코드를 업데이트할 수도 있습니다 .

ArticleRecord article = context.fetchOne(Article.ARTICLE, Article.ARTICLE.ID.eq(1));
article.setTitle("A New Article Title");
article.store();

저장 방법은 반환 1 작업이 성공 또는 경우 0 업데이트가 필요 아니었다면. 예를 들어 조건과 일치하는 항목이 없습니다.

6.4. 삭제 중

주어진 레코드를 삭제하기 위해 DSLContext 객체 에서 delete 메소드를 사용할 수 있습니다 . 삭제 조건은 다음 where 절의 매개변수로 전달되어야 합니다 .

context.delete(Article.ARTICLE)
  .where(Article.ARTICLE.ID.eq(1))
  .execute();

삭제 쿼리는 실행 메서드를 호출한 후에만 실행됩니다 . 반환 값으로 삭제된 레코드 수와 동일한 정수를 얻습니다.

삭제 메소드 를 실행하여 이미 가져온 레코드를 삭제할 수도 있습니다 .

ArticleRecord articleRecord = context.fetchOne(Article.ARTICLE, Article.ARTICLE.ID.eq(1));
articleRecord.delete();

삭제 방법은 반환 1 작업이 성공 또는 경우 0 삭제가 필요 아니었다면. 예를 들어 조건과 일치하는 항목이 없는 경우입니다.

7. 결론

이 기사에서는 jOOQ 프레임워크를 사용하여 간단한 CRUD 애플리케이션을 구성하고 만드는 방법을 배웠습니다. 평소와 같이 모든 소스 코드는 GitHub에서 사용할 수 있습니다.

Persistence footer banner