This library provides a convenient way to connect with SQL-databases via JDBC, and easily make SQL-requests.
BacKT SQL is a part of «Back-end Kotlin Tool Set» that consists of:
- BacKT SQL (this one)
- BacKT WebServer (a Netty-based web-server)
It also uses KotLog for logging.
repositories {
maven { url "http://dl.bintray.com/azadev/maven" }
}
dependencies {
compile "azadev.backt:backt_sql:0.7.1"
}
And of course you need a JDBC database connector. For example, MySQL Connector/J:
dependencies {
// ...
compile "mysql:mysql-connector-java:5.1.42"
}
BacKT SQL consists of 4 main parts:
Database
ConnectionPool
QueryBuilder
- Small utilities
The main character of the library is the Database
class. It holds a connection to the database and allows to perform queries and transactions.
// Must be called once, as your application starts:
Database.loadDriver("com.mysql.jdbc.Driver")
val db = Database.connect("jdbc:mysql://localhost:3306/dbname", "user", "pass")
val resultSet = db.executeQuery("SELECT * FROM t WHERE id = ?", 234)
val count = db.executeUpdate("UPDATE t SET id = ?", 234)
Database
provides methods to perform transactions: disableAutoCommit
, enableAutoCommit
, commit
, rollback
. Here is an example usage:
db.disableAutoCommit()
val rows = db.executeUpdate("UPDATE t SET id = ?", 234)
if (rows == 0) {
// log error
db.rollback()
}
else {
// do something else
db.commit()
}
Read more about transactions on JDBC Docs.
Another must-have tool is the ConnectionPool
. It caches database connections so they can be reused for future requests:
val pool = ConnectionPool(maxSize = 50) { Database.connect(url, user, pass) }
// Obtain a connection:
val db = pool.obtain()
// ... do some work ...
// Then release:
pool.release(db)
There is a couple of convenience methods named use
and useAndGet
. useAndGet
returns the result of its lambda, use
doesn't:
pool.use { db ->
db.executeUpdate(...)
}
val res = pool.useAndGet { db ->
db.executeQuery(...)
}
QueryBuilder
helps to build and execute SQL-statements. For example, the methods listed below are performing exacly the same request:
fun getUser(db: Database, id: Int, email: String): ResultSet {
return db.executeQuery(
"SELECT `name`, `surname` FROM `user` WHERE `id`=$id AND `email`=? LIMIT 1",
email
)
}
fun getUser(db: Database, id: Int, email: String): ResultSet {
return QueryBuilder()
.select("name", "surname")
.from("user")
.where("id", id)
.wherep("email", email)
.limit(1)
.executeQuery(db)
}
QueryBuilder
is an extremely useful helper when it comes to build SQL-quesries that depend on some conditions:
fun getUser(db: Database, id: Int? = null, email: String? = null, order: String? = null, desc: Boolean = false): ResultSet {
val q = QueryBuilder().select().from("user")
if (id != null)
q.where("id", id)
if (email != null)
q.wherep("email", email)
if (order != null)
q.orderBy(order, desc)
return q.executeQuery(db)
}
count
, countByte
, countLong
, countFloat
, countDouble
:
val countInt = db.executeUpdate("UPDATE ...").count
val idLong = db.executeQuery("SELECT id FROM ...").countLong
val numFloat = db.executeQuery("SELECT rating FROM ...").countFloat
single
, toList
:
class User(res: ResultSet) { ... }
val user = db.executeQuery("SELECT * FROM user LIMIT 1").single(::User)
val userList = db.executeQuery("SELECT * FROM user").toList(::User)
... and others: escapeSqlLiteral
, escapeSqlIdentifier
, makeValueSet
, asParameterized
This software is released under the MIT License. See LICENSE.md for details.