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 스키마를 생성해 보겠습니다. 간단한 Author 및 Article 관계를 사용합니다.
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에서 사용할 수 있습니다.