Kotlin 封装 Realm 操作举例

先在项目的build.gradle配置好kotlin和realm

buildscript {
    ext.kotlin_version = '1.2.10'
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "io.realm:realm-gradle-plugin:3.1.1"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

新建一个实体类Person.kt,可以查看官方的例子

open class Person(
        @PrimaryKey public open var name: String = "",
        public open var age: Int = 0,
        public open var sex: String = "",
        @Ignore public open var tempReference: Int = 0,
        public open var id: Long = 0
) : RealmObject() {}

再来看一下封装好的CRUD操作RealmExtensions.kt,来自Víctor Manuel Pineda Murcia

typealias Query<T> = RealmQuery<T>.() -> Unit

/**
 * Created by victor on 2/1/17.
 * Extensions for Realm. All methods here are synchronous.
 */

/**
 * Query to the database with RealmQuery instance as argument
 */
fun <T : RealmModel> T.query(query: Query<T>): List<T> {
    getRealmInstance().use { realm ->
        val result = realm.where(javaClass).withQuery(query).findAll()
        return realm.copyFromRealm(result)
    }
}

/**
 * Query to the database with RealmQuery instance as argument
 */
inline fun <reified T : RealmModel> query(query: Query<T>): List<T> {
    getRealmInstance<T>().use { realm ->
        val result = realm.where(T::class.java).runQuery(query).findAll()
        return realm.copyFromRealm(result)
    }
}

/**
 * Query to the database with RealmQuery instance as argument and returns all items founded
 */
fun <T : RealmModel> T.queryAll(): List<T> {
    getRealmInstance().use { realm ->
        val result = realm.where(this.javaClass).findAll()
        return realm.copyFromRealm(result)
    }
}

inline fun <reified T : RealmModel> queryAll(): List<T> {
    getRealmInstance<T>().use { realm ->
        val result = realm.where(T::class.java).findAll()
        return realm.copyFromRealm(result)
    }
}

/**
 * Query to the database with RealmQuery instance as argument. Return first result, or null.
 */
fun <T : RealmModel> T.queryFirst(): T? {
    getRealmInstance().use { realm ->
        val item: T? = realm.where(this.javaClass).findFirst()
        return if (item != null && RealmObject.isValid(item)) realm.copyFromRealm(item) else null
    }
}

inline fun <reified T : RealmModel> queryFirst(): T? {
    getRealmInstance<T>().use { realm ->
        val item: T? = realm.where(T::class.java).findFirst()
        return if (item != null && RealmObject.isValid(item)) realm.copyFromRealm(item) else null
    }
}

/**
 * Query to the database with RealmQuery instance as argument. Return first result, or null.
 */
fun <T : RealmModel> T.queryFirst(query: Query<T>): T? {
    getRealmInstance().use { realm ->
        val item: T? = realm.where(this.javaClass).withQuery(query).findFirst()
        return if (item != null && RealmObject.isValid(item)) realm.copyFromRealm(item) else null
    }
}

inline fun <reified T : RealmModel> queryFirst(query: Query<T>): T? {
    getRealmInstance<T>().use { realm ->
        val item: T? = realm.where(T::class.java).runQuery(query).findFirst()
        return if (item != null && RealmObject.isValid(item)) realm.copyFromRealm(item) else null
    }
}

/**
 * Query to the database with RealmQuery instance as argument. Return last result, or null.
 */
fun <T : RealmModel> T.queryLast(): T? {
    getRealmInstance().use { realm ->
        val result = realm.where(this.javaClass).findAll()
        return if (result != null && result.isNotEmpty()) realm.copyFromRealm(result.last()) else null
    }
}

inline fun <reified T : RealmModel> queryLast(): T? {
    getRealmInstance<T>().use { realm ->
        val result: RealmResults<T> = realm.where(T::class.java).findAll()
        return if (result.isNotEmpty()) realm.copyFromRealm(result.last()) else null
    }
}

/**
 * Query to the database with RealmQuery instance as argument. Return last result, or null.
 */
fun <T : RealmModel> T.queryLast(query: Query<T>): T? {
    getRealmInstance().use { realm ->
        val result = realm.where(this.javaClass).withQuery(query).findAll()
        return if (result != null && result.isNotEmpty()) realm.copyFromRealm(result.last()) else null
    }
}

inline fun <reified T : RealmModel> queryLast(query: Query<T>): T? {
    getRealmInstance<T>().use { realm ->
        val result: RealmResults<T> = realm.where(T::class.java).runQuery(query).findAll()
        return if (result.isNotEmpty()) realm.copyFromRealm(result.last()) else null
    }
}


/**
 * Query to the database with RealmQuery instance as argument
 */
fun <T : RealmModel> T.querySorted(fieldName: String, order: Sort, query: Query<T>): List<T> {
    getRealmInstance().use { realm ->
        val result = realm.where(this.javaClass).withQuery(query).findAll().sort(fieldName, order)
        return realm.copyFromRealm(result)
    }
}

inline fun <reified T : RealmModel> querySorted(fieldName: String, order: Sort, query: Query<T>): List<T> {
    getRealmInstance<T>().use { realm ->
        val result = realm.where(T::class.java).runQuery(query).findAll().sort(fieldName, order)
        return realm.copyFromRealm(result)
    }
}

/**
 * Query to the database with a specific order and a RealmQuery instance as argument
 */
fun <T : RealmModel> T.querySorted(fieldName: List<String>, order: List<Sort>, query: Query<T>): List<T> {
    getRealmInstance().use { realm ->
        val result = realm.where(this.javaClass).withQuery(query).findAll().sort(fieldName.toTypedArray(), order.toTypedArray())
        return realm.copyFromRealm(result)
    }
}

inline fun <reified T : RealmModel> querySorted(fieldName: List<String>, order: List<Sort>, query: Query<T>): List<T> {
    getRealmInstance<T>().use { realm ->
        val result = realm.where(T::class.java).runQuery(query).findAll().sort(fieldName.toTypedArray(), order.toTypedArray())
        return realm.copyFromRealm(result)
    }
}

/**
 * Query to the database with a specific order
 */
fun <T : RealmModel> T.querySorted(fieldName: String, order: Sort): List<T> {
    getRealmInstance().use { realm ->
        val result = realm.where(this.javaClass).findAll().sort(fieldName, order)
        return realm.copyFromRealm(result)
    }
}

inline fun <reified T : RealmModel> querySorted(fieldName: String, order: Sort): List<T> {
    getRealmInstance<T>().use { realm ->
        val result = realm.where(T::class.java).findAll().sort(fieldName, order)
        return realm.copyFromRealm(result)
    }
}

/**
 * Query to the database with a specific order
 */
fun <T : RealmModel> T.querySorted(fieldName: List<String>, order: List<Sort>): List<T> {
    getRealmInstance().use { realm ->
        val result = realm.where(this.javaClass).findAll().sort(fieldName.toTypedArray(), order.toTypedArray())
        return realm.copyFromRealm(result)
    }
}

inline fun <reified T : RealmModel> querySorted(fieldName: List<String>, order: List<Sort>): List<T> {
    getRealmInstance<T>().use { realm ->
        val result = realm.where(T::class.java).findAll().sort(fieldName.toTypedArray(), order.toTypedArray())
        return realm.copyFromRealm(result)
    }
}

/**
 * Utility extension for modifying database. Create a transaction, run the function passed as argument,
 * commit transaction and close realm instance.
 */
fun Realm.transaction(action: (Realm) -> Unit) {
    use { executeTransaction { action(this) } }
}

/**
 * Creates a new entry in database. Usefull for RealmObject with no primary key.
 */
fun <T : RealmModel> T.create() {
    getRealmInstance().transaction { it.copyToRealm(this) }
}

/**
 * Creates a new entry in database. Useful for RealmObject with no primary key.
 * @return a managed version of a saved object
 */
fun <T : RealmModel> T.createManaged(realm: Realm): T {
    var result: T? = null
    realm.executeTransaction { result = it.copyToRealm(this) }
    return result!!
}

/**
 * Creates or updates a entry in database. Requires a RealmObject with primary key, or IllegalArgumentException will be thrown
 */
fun <T : RealmModel> T.createOrUpdate() {
    getRealmInstance().transaction { it.copyToRealmOrUpdate(this) }
}

/**
 * Creates or updates a entry in database. Requires a RealmObject with primary key, or IllegalArgumentException will be thrown
 * @return a managed version of a saved object
 */
fun <T : RealmModel> T.createOrUpdateManaged(realm: Realm): T {
    var result: T? = null
    realm.executeTransaction { result = it.copyToRealmOrUpdate(this) }
    return result!!
}

/**
 * Delete all entries of this type in database
 */
fun <T : RealmModel> T.deleteAll() {
    getRealmInstance().transaction { it.where(this.javaClass).findAll().deleteAllFromRealm() }
}

inline fun <reified T : RealmModel> deleteAll() {
    getRealmInstance<T>().transaction { it.where(T::class.java).findAll().deleteAllFromRealm() }
}

/**
 * Delete all entries returned by the specified query
 */
fun <T : RealmModel> T.delete(myQuery: Query<T>) {
    getRealmInstance().transaction {
        it.where(this.javaClass).withQuery(myQuery).findAll().deleteAllFromRealm()
    }
}

inline fun <reified T : RealmModel> delete(crossinline query: Query<T>) {
    getRealmInstance<T>().transaction {
        it.where(T::class.java).runQuery(query).findAll().deleteAllFromRealm()
    }
}

/**
 * Update first entry returned by the specified query
 */
inline fun <reified T : RealmModel> T.queryAndUpdate(noinline query: Query<T>, noinline modify: (T) -> Unit) {
    queryFirst(query).let {
        modify(this)
        save()
    }
}

/**
 * Creates a new entry in database or updates an existing one. If entity has no primary key, always create a new one.
 * If has primary key, it tries to updates an existing one.
 */
fun <T : RealmModel> T.save() {
    getRealmInstance().transaction { realm ->
        realm.copyToRealm(this)
    }
}



/**
 * Get count of entries
 */
fun <T : RealmModel> T.count(): Long {
    getRealmInstance().use { realm ->
        return realm.where(this::class.java).count()
    }
}

fun <T : RealmModel> T.count(realm: Realm): Long {
    return realm.where(this::class.java).count()
}

inline fun <reified T : RealmModel> count(): Long {
    getRealmInstance<T>().use { realm ->
        return realm.where(T::class.java).count()
    }
}

inline fun <reified T : RealmModel> count(realm: Realm): Long {
    return realm.where(T::class.java).count()
}

inline fun <reified T : RealmModel> count(query: Query<T>): Long {
    getRealmInstance<T>().use { realm ->
        return realm.where(T::class.java).runQuery(query).count()
    }
}

/**
 * UTILITY METHODS
 */
private fun <T> T.withQuery(block: (T) -> Unit): T {
    block(this); return this
}

/**
 * UTILITY METHODS
 */
inline fun <reified T : RealmModel> RealmQuery<T>.runQuery(block: RealmQuery<T>.() -> Unit): RealmQuery<T> {
    block(this); return this
}

然后我们就可以愉快的使用了

class MainActivity : AppCompatActivity(), View.OnClickListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onClick(p0: View?) {
        when (p0?.id) {
            R.id.tvHello -> {
                //Person().createOrUpdate()
                Toast.makeText(this, Person().queryFirst().toString(), Toast.LENGTH_SHORT).show()
                //Person().count()
            }
        }
    }
}
文章目录
|