中文版请见这里
Welcome to use SQLlin !!!
Add the dependencies of sqllin-dsl, sqllin-driver and sqllin-processor into your build.gradle.kts
:
plugins {
kotlin("multiplatform")
kotlin("plugin.serialization")
id("com.android.library")
id("com.google.devtools.ksp")
}
val sqllinVersion = "1.4.0"
kotlin {
// ......
sourceSets {
val commonMain by getting {
kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
dependencies {
// sqllin-dsl
implementation("com.ctrip.kotlin:sqllin-dsl:$sqllinVersion")
// sqllin-driver
implementation("com.ctrip.kotlin:sqllin-driver:$sqllinVersion")
// The sqllin-dsl serialization and deserialization depends on kotlinx-serialization
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3")
// Since 1.2.2, sqllin-dsl depends on kotlinx.coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
}
}
// ......
}
}
// KSP dependencies
dependencies {
// sqllin-processor
add("kspCommonMainMetadata", "com.ctrip.kotlin:sqllin-processor:$sqllinVersion")
}
Note: If you want to add dependencies of SQLlin into your Kotlin/Native executable program projects, sometimes you need to add the
linkerOpts
of SQLite into yourbuild.gradle.kts
correctly. You can refer to issue #48 to get more information.
You can create the Database
instance in sample:
import com.ctrip.sqllin.dsl.Database
val database = Database(name = "Person.db", path = getGlobalPath(), version = 1)
The DatabasePath
is the second parameter path
's type, it is represented differently on different platforms.
On Android, you can get it through Context
, and you can get it through string on native platforms.
For example, you can define a expect function in your common source set:
import com.ctrip.sqllin.driver.DatabasePath
expect fun getGlobalDatabasePath(): DatabasePath
In your Android source set, you can implement it by:
import android.content.Context
import com.ctrip.sqllin.driver.DatabasePath
import com.ctrip.sqllin.driver.toDatabasePath
actual fun getGlobalDatabasePath(): DatabasePath =
applicationContext.toDatabasePath()
val applicationContext: Context
get() {
// Use your own way to get `applicationContext`
}
In your iOS source set (similar with other Apple platforms), you can implement it by:
import com.ctrip.sqllin.driver.DatabasePath
import com.ctrip.sqllin.driver.toDatabasePath
actual fun getGlobalDatabasePath(): DatabasePath =
(NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory,
NSUserDomainMask, true).firstOrNull() as? String ?: ""
).toDatabasePath()
You can config more SQLite arguments when you create the Database
instance:
import com.ctrip.sqllin.driver.DatabaseConfiguration
import com.ctrip.sqllin.dsl.Database
val database = Database(
DatabaseConfiguration(
name = "Person.db",
path = getGlobalDatabasePath(),
version = 1,
isReadOnly = false,
inMemory = false,
journalMode = JournalMode.WAL,
synchronousMode = SynchronousMode.NORMAL,
busyTimeout = 5000,
lookasideSlotSize = 0,
lookasideSlotCount = 0,
create = {
it.execSQL("create table person (id integer primary key autoincrement, name text, age integer)")
},
upgrade = { databaseConnection, oldVersion, newVersion -> }
)
)
Note, because of limitation by Android Framework, the inMemory
, busyTimeout
, lookasideSlotSize
, lookasideSlotCount
only work on Android 9 and higher. And, because sqlite-jdbc(SQLlin is based on it on JVM) doesn't support
sqlite3_config()
, the lookasideSlotSize
and lookasideSlotCount
don't work on JVM target.
Now, the operations that change database structure haven't been supported by DSL yet. So, you need to write these SQL statements by string
as in create
and upgrade
parameters.
Usually, you just need to create one Database
instance in your component lifecycle. So, you need to close database manually when the lifecycle ended:
override fun onDestroy() {
database.close()
}
In sqllin-dsl, you can insert and query objects directly. So, you need to use the correct way to define your data classes. For example:
import com.ctrip.sqllin.dsl.annotation.DBRow
import kotlinx.serialization.Serializable
@DBRow(tableName = "person")
@Serializable
data class Person(
val name: String,
val age: Int,
)
Your database entities' property names should be same with the database table's column names. The database entities cannot have properties with names different from all column names in the table. But the count of your database entities' properties can less than the count of columns.
The @DBRow
's param tableName
represents the table name in Database, please ensure pass
the correct value. If you don't pass the parameter manually, sqllin-processor will use the class
name as table name, for example, Person
's default table name is "Person".
In sqllin-dsl, objects are serialized to SQL and deserialized from cursor depend on kotlinx.serialization. So, you also need to add the @Serializable
onto your data classes. Therefore, if
you want to ignore some properties when serialization or deserialization and Table
classes generation, you can annotate your properties with kotlinx.serialization.Transient
.
You have learned all the preparations, you can start learn how to operate database now: