Skip to content

JVM에서 HSQL 시작하기

실험적

HSQL 지원은 인큐베이팅 단계이며, 방언(dialect)의 일부 기능이 아직 미완성 상태입니다. 지원되지 않는 방언 기능을 발견하면 sql-psi에 보고해 주십시오.

먼저 프로젝트에 Gradle 플러그인을 적용합니다.

kotlin
plugins {
  id("app.cash.sqldelight") version "2.1.0"
}
 
repositories {
  google()
  mavenCentral()
}

sqldelight {
  databases {
    create("Database") {
      packageName.set("com.example")
    }
  }
}
groovy
plugins {
  id "app.cash.sqldelight" version "2.1.0"
}

repositories {
  google()
  mavenCentral()
}

sqldelight {
  databases {
    Database { // 이는 생성될 데이터베이스 클래스의 이름이 됩니다.
      packageName = "com.example"
    }
  }
}

SQLDelight는 데이터베이스의 스키마를 알아야 합니다. 일반적으로 데이터베이스 스키마를 설정하는 두 가지 접근 방식이 있습니다. "Fresh Schema" 접근 방식은 빈 데이터베이스에서 시작하여 원하는 상태로 만들기 위해 필요한 모든 구문이 한 번에 모두 적용된다고 가정합니다. 반면에 "Migration Schema" 접근 방식은 이미 데이터베이스와 스키마가 설정되어 있으며(예: 기존 운영 데이터베이스), 시간이 지남에 따라 마이그레이션을 점진적으로 적용하여 데이터베이스의 스키마를 업데이트한다고 가정합니다.

SQLDelight에서 이러한 접근 방식은 "Fresh Schema"를 위해 .sq 파일에 테이블 정의를 작성하거나, "Migration Schema"를 위해 .sqm 파일에 마이그레이션 구문을 작성하는 것으로 해석됩니다. 두 경우 모두 SQL _쿼리_는 .sq 파일에 작성됩니다(여기에서 보여주는 것처럼).

Fresh Schema

SQL 문은 src/main/sqldelight 경로 아래의 .sq 파일에 작성합니다. 일반적으로 .sq 파일의 첫 번째 문은 테이블을 생성하지만, 인덱스를 생성하거나 기본 콘텐츠를 설정할 수도 있습니다.

sql
CREATE TABLE hockeyPlayer (
  player_number INTEGER PRIMARY KEY NOT NULL,
  full_name TEXT NOT NULL
);

CREATE INDEX hockeyPlayer_full_name ON hockeyPlayer(full_name);

INSERT INTO hockeyPlayer (player_number, full_name)
VALUES (15, 'Ryan Getzlaf');

동일한 .sq 파일에 런타임에 실행될 SQL 구문을 배치하기 시작할 수 있습니다.

Migration Schema

먼저, Gradle이 마이그레이션을 사용하여 스키마를 구성하도록 설정합니다:

kotlin
sqldelight {
  databases {
    create("Database") {
      ...
      srcDirs("sqldelight")
      deriveSchemaFromMigrations.set(true)
    }
  }
}
groovy
sqldelight {
  databases {
    Database {
      ...
      srcDirs "sqldelight"
      deriveSchemaFromMigrations = true
    }
  }
}

마이그레이션 파일은 .sqm 확장자를 가지며, 마이그레이션 파일이 실행되는 순서를 나타내는 숫자가 파일 이름에 포함되어야 합니다. 예를 들어, 다음 계층 구조에서:

src
`-- main
    `-- sqldelight
        |-- v1__backend.sqm
        `-- v2__backend.sqm

SQLDelight는 v1__backend.sqm을 적용한 다음 v2__backend.sqm을 적용하여 스키마를 생성합니다. 이러한 파일에 일반 SQL CREATE/ALTER 구문을 배치하세요. 다른 서비스가 (Flyway와 같이) 마이그레이션 파일을 읽는 경우, 마이그레이션에 대한 정보와 유효한 SQL을 출력하는 방법을 반드시 읽어보세요.

Typesafe SQL

런타임에 SQL 구문을 실행하기 전에, 데이터베이스에 연결하기 위해 SqlDriver를 생성해야 합니다. 가장 쉬운 방법은 Hikari 또는 다른 연결 관리자로부터 얻는 DataSource를 사용하는 것입니다.

kotlin
dependencies {
  implementation("app.cash.sqldelight:jdbc-driver:2.1.0")
}
groovy
dependencies {
  implementation "app.cash.sqldelight:jdbc-driver:2.1.0"
}
kotlin
val driver: SqlDriver = dataSource.asJdbcDriver()

스키마를 초기 테이블 생성 구문으로 지정하든 마이그레이션을 통해 지정하든 상관없이, 런타임 SQL은 .sq 파일에 들어갑니다.

타입 안전 쿼리 정의

SQLDelight는 .sq 파일에 있는 레이블이 지정된 SQL 문에 대해 타입 안전 함수를 생성합니다.

sql
selectAll:
SELECT *
FROM hockeyPlayer;

insert:
INSERT INTO hockeyPlayer(player_number, full_name)
VALUES (?, ?);

insertFullPlayerObject:
INSERT INTO hockeyPlayer(player_number, full_name)
VALUES ?;

레이블이 지정된 문을 포함하는 .sq 파일마다 "Queries" 객체가 생성됩니다. 예를 들어, 위에서 보인 Player.sq 파일에 대해 PlayerQueries 객체가 생성됩니다. 이 객체는 생성된 타입 안전 함수를 호출하는 데 사용될 수 있으며, 이 함수들은 실제 SQL 문을 실행합니다.

kotlin
fun doDatabaseThings(driver: SqlDriver) {
  val database = Database(driver)
  val playerQueries: PlayerQueries = database.playerQueries

  println(playerQueries.selectAll().AsList()) 
  // [HockeyPlayer(15, "Ryan Getzlaf")]

  playerQueries.insert(player_number = 10, full_name = "Corey Perry")
  println(playerQueries.selectAll().AsList()) 
  // [HockeyPlayer(15, "Ryan Getzlaf"), HockeyPlayer(10, "Corey Perry")]

  val player = HockeyPlayer(10, "Ronald McDonald")
  playerQueries.insertFullPlayerObject(player)
}

이것으로 끝입니다! 사이드바의 다른 페이지에서 다른 기능들을 확인하십시오.