@cxm-2016
2017-02-04T15:49:21.000000Z
字数 4034
阅读 4156
Kotlin
版本:1
作者:陈小默
声明:禁止转载
原文地址:Anko-SQLite
我们需要在你的 build.gradle 文件添加下面的内容:
compile 'org.jetbrains.anko:anko-sqlite:0.9'
import org.jetbrains.anko.db.*
传统的数据库访问方式,我们需要创建一个DatabaseOpenHelper类,然后重写其中包含的方法。就像下面这个样子:
class MyDatabaseOpenHelper(ctx: Context) : ManagedSQLiteOpenHelper(ctx, "MyDatabase", null, 1) {companion object {private var instance: MyDatabaseOpenHelper? = null@Synchronizedfun getInstance(ctx: Context): MyDatabaseOpenHelper {if (instance == null) {instance = MyDatabaseOpenHelper(ctx.getApplicationContext())}return instance!!}}override fun onCreate(db: SQLiteDatabase) {// 创建数据库db?.createTable("Customer", ifNotExists = true,"_id" to INTEGER + PRIMARY_KEY + UNIQUE,"name" to TEXT,"photo" to BLOB)}override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {// 如果需要的话,在这里升级数据库db?.dropTable("User", true)}}// 扩展Context的访问方式val Context.database: MyDatabaseOpenHelperget() = MyDatabaseOpenHelper.getInstance(getApplicationContext())
对于Anko,我们只需要通过下面这段简单的代码就能够创建一个数据库:
database.use {// 现在`this`就是一个SQLiteDatabase实例}
接下来写一段异步加载数据库并回调的示例:
class SomeActivity : Activity() {private fun loadAsync() {doAsync {val result = database.use {// TODO}uiThread { loadComplete(result) }}}}
使用Anko能够方便的创建和销毁一张数据表,它的语法像这样:
database.use {createTable("Customer", true,"_id" to INTEGER + PRIMARY_KEY + UNIQUE,"name" to TEXT,"photo" to BLOB)}
目前支持五种类型: NULL, INTEGER, REAL, TEXT 和BLOB. 对于PRIMARY KEY 或者 UNIQUE 的设定,可以在类型之后使用+设置.
使用dropTable方法可以销毁数据表:
dropTable("User", true)
通常情况下,我们需要使用ContentValues对象来向表中插入一行数据,就像下面这样:
val values = ContentValues()values.put("_id", 5)values.put("name", "John Smith")values.put("email", "user@domain.org")db.insert("User", null, values)
Anko 使用更简洁的方式来实现插入操作:
db.insert("User","_id" to 42,"name" to "John","email" to "user@domain.org")
也可以在数据库初始化的时候调用:
database.use {insert("User","_id" to 42,"name" to "John","email" to "user@domain.org"}
insertOrThrow(), replace(), replaceOrThrow() 都是可用的方法。
在查询过程中,Anko提供了如下约束方法:
| Method | Description |
|---|---|
column(String) |
Add a column to select query |
distinct(Boolean) |
Distinct query |
where(String) |
Specify raw String where query |
where(String, args) :star: |
Specify a where query with arguments |
where?(String, args) |
Specify a where query with ? mark arguments |
orderBy(String, [ASC/DESC]) |
Order by this column |
groupBy(String) |
Group by this column |
limit(count: Int) |
Limit query result row count |
limit(offset: Int, count: Int) |
Limit query result row count with an offset |
having(String) |
Specify raw having expression |
having(String, args) :star: |
Specify a having expression with arguments |
查询过程支持参数解析,于是我们可以将一次查询写成下面的样子:
db.select("User", "name").where("(_id > {userId}) and (name = {userName})","userName" to "John","userId" to 42)
在这里{userId}部分会被替换为42 并且 {userName}被替换为'John'`。
where?方法仅支持 String 类型.
通过 exec() 方法我们可以执行此次插叙.它通过扩展接受一个Lambda表达式 Cursor.() -> T.
db.select("User", "email").exec {// Doing some stuff with emails}
当我们或得到 Cursor 对象之后, Anko提供了如下方法解析对象。
| Method | Description |
|---|---|
parseSingle(rowParser): T |
严格的解析一行,或得到一个对象。 |
parseOpt(rowParser): T? |
解析一行得到对象,或没有数据返回null。 |
parseList(rowParser): List<T> |
解析任意多行数据。 |
目前支持两种类型的解析器:
interface RowParser<T> {fun parseRow(columns: Array<Any>): T}interface MapRowParser<T> {fun parseRow(columns: Map<String, Any>): T}
Anko还提供了解析单行单列数据的解析器:
ShortParserIntParserLongParserFloatParserDoubleParserStringParserBlobParser另外你也可以自己创建一个Bean类用于解析,必须将属性声明到主构造器当中:
class Person(val firstName: String, val lastName: String, val age: Int)
通过上面的类创建解析器:
val rowParser = classParser<Person>()
目前Anko不支持通过主构造器中的可选参数创建解析器。目前使用的是通过Java反射构造方法传入传入生成解析器。
让我们自定义个行解析器 (Int, String, String).最简单的方式如下:
class MyRowParser : RowParser<Triple<Int, String, String>> {override fun parseRow(columns: Array<Any>): Triple<Int, String, String> {return Triple(columns[0] as Int, columns[1] as String, columns[2] as String)}}
我们可以通过Lambda表达式简化上述过程:
val parser = rowParser { id: Int, name: String, email: String ->Triple(id, name, email)}
不要忘记关闭Cursor对象
将User表中符合条件的name属性设置为Alice
update("User", "name" to "Alice").where("_id = {userId}", "userId" to 42).exec()
我们也可以通过 where?() 函数来使用传统的占位方式:
update("User", "name" to "Alice").`where?`("_id = ?", 42).exec()
以下方法与允许你在其中使用事务操作一个数据库。
transaction {// Your transaction code}
Transaction will be marked marked as successful if no exception was thrown inside the {} block.