Skip to content

Getting Started with MySQL

First apply the gradle plugin in your project.

buildscript {
  repositories {
    google()
    mavenCentral()
  }
  dependencies {
    classpath 'com.squareup.sqldelight:gradle-plugin:1.5.4'
  }
}

apply plugin: 'com.squareup.sqldelight'

sqldelight {
  Database { // This will be the name of the generated database class.
    packageName = "com.example"
    dialect = "mysql"
  }
}

SQLDelight needs to know the schema of your database. If you always create your schema fresh with create table statements, you'll want to put those statements in .sq files, as shown here. If you apply migration files to an already running database, you'll want to rename your migration files to .sqm files, as shown here

Fresh Schema

Put your SQL statements in a .sq file under src/main/sqldelight. Typically the first statement in the SQL file creates a table.

-- src/main/sqldelight/com/example/sqldelight/hockey/data/Player.sq

CREATE TABLE hockeyPlayer (
  player_number INTEGER 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');

In the same .sq files you can start placing your sql statements to be executed at runtime.

Migration Schema

First, configure gradle to use migrations to assemble the schema:

sqldelight {
  Database {
    ...
    sourceFolders = ["sqldelight"]
    deriveSchemaFromMigrations = true
  }
}

Migration files have the extension .sqm, and must have a number in their file name indicating what order the migration file runs in. For example, given this hierarchy:

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

SQLDelight will create the schema by applying v1__backend.sqm and then v2__backend.sqm. Place your normal SQL CREATE/ALTER statements in these files. If another service reads from your migrations files (like flyway), make sure to read the info on migrations and how to output valid SQL.

Typesafe SQL

Before you're able to execute SQL statements at runtime, you need to create a SqlDriver to connect to your database. The easiest way is off of a DataSource that you would get from hikari or other connection managers.

dependencies {
  implementation "com.squareup.sqldelight:jdbc-driver:1.5.4"
}
val driver: SqlDriver = dataSource.asJdbcDriver()

Regardless of if you specify the schema as fresh create table statements or through migrations, runtime SQL goes in .sq files.

SQL statements inside a .sq file can be labeled to have a typesafe function generated for them available at runtime.

selectAll:
SELECT *
FROM hockeyPlayer;

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

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

Files with labeled statements in them will have a queries file generated from them that matches the .sq file name - putting the above sql into Player.sq generates PlayerQueries.kt. To get a reference to PlayerQueries you need to wrap the driver we made above:

// In reality the database and driver above should be created a single time
// and passed around using your favourite dependency injection/service
// locator/singleton pattern.
val database = Database(driver)

val playerQueries: PlayerQueries = database.playerQueries

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

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

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

And that's it! Check out the other pages on the sidebar for other functionality.