Skip to content

MySQL

Real MySQL in a container or wired to existing infra. Same DSL shape as PostgreSQL and MSSQL: shouldExecute(sql), shouldQuery<T>(sql, mapper), migrations, raw ops.

Open in setup wizard

MySQL — wizard-synced snippet

Gradle

testImplementation("com.trendyol:stove-mysql")

Stove configuration

Stove().with {
    mysql {
      MySqlOptions(
        configureExposedConfiguration = { cfg ->
          listOf("spring.datasource.url=${cfg.jdbcUrl}")
        }
      )
    }
}

Test DSL

stove {
    mysql { shouldExecute("SELECT 1") }
}

In 30 seconds Register mysql { MySqlOptions(databaseName, ...) }. Parameterized queries with ?. Row mapper returns your domain type. AUTO_INCREMENT IDs work as expected.

Configure

Stove().with {
  mysql {
    MySqlOptions(
      databaseName = "testdb",
      configureExposedConfiguration = { cfg ->
        listOf(
          "spring.datasource.url=${cfg.jdbcUrl}",
          "spring.datasource.username=${cfg.username}",
          "spring.datasource.password=${cfg.password}"
        )
      }
    )
  }
}.run()

Migrations

class CreateUsersTable : DatabaseMigration<MySqlMigrationContext> {
  override val order = 1
  override suspend fun execute(ctx: MySqlMigrationContext) {
    ctx.operations.execute(
      """
      CREATE TABLE IF NOT EXISTS users (
        id BIGINT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(100) NOT NULL,
        email VARCHAR(100) NOT NULL UNIQUE,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
      )
      """.trimIndent()
    )
  }
}

mysql {
  MySqlOptions(/* ... */).migrations { register<CreateUsersTable>() }
}

DSL

data class User(val id: Long, val name: String, val email: String?)

stove {
  mysql {
    shouldExecute("INSERT INTO users (name, email) VALUES ('Alice', 'a@x.com')")

    shouldQuery<User>(
      query = "SELECT * FROM users WHERE email = ?",
      mapper = { row ->
        User(
          id = row.long("id"),
          name = row.string("name"),
          email = row.stringOrNull("email")
        )
      }
    ) { users ->
      users shouldHaveSize 1
    }
  }
}

Provided MySQL

mysql {
  MySqlOptions.provided(
    jdbcUrl = "jdbc:mysql://shared-mysql:3306/test",
    username = "test",
    password = "test",
    configureExposedConfiguration = { cfg -> listOf(/* ... */) }
  )
}

Pitfalls

Symptom Fix
Public Key Retrieval is not allowed Append ?allowPublicKeyRetrieval=true&useSSL=false to the JDBC URL
Charset issues Use utf8mb4 collation in CREATE TABLE for full Unicode
AUTO_INCREMENT mismatch across runs Don't assert exact IDs; verify by business key

Pairs well with