如何使用LinkingObject for android

时间:2018-03-26 03:29:13

标签: android kotlin realm rlmlinkingobjects

我想使用Realm建立像SQLite这样的关系。

  1. 如果在添加父表时没有子表,如何添加RealmList?
  2. 父表与子表之间是否存在实时链接?
  3. 如何迁移RealmList,@ LinkingObject
  4. 1.Parent Table

    @RealmClass
    open class ParentTable : RealmObject() {
    
        @PrimaryKey
        open var id : Long = 0
    
        open var parentname : String? = null
    
        var child : RealmList<ChildTable>? = null
    
    }
    

    2.Child Table

    @RealmClass
    open class ChildTable : RealmObject() {
    
        @PrimaryKey
        open var id : Long = 0
    
        open var parentId : Long? = 0    
    
        open var childName : String? = null
    
        @LinkingObjects("child")
        val parent : RealmResults<ParentTable>? = null
    
    }
    

    3.Application class

    class HanmoApplication : MultiDexApplication() {
    
        override fun onCreate() {
            super.onCreate()
    
            initRealm()
        }
    
        private fun initRealm() {
    
            Realm.init(this)
    
            val config = RealmConfiguration.Builder()
                    .name("hanmo.realm")
                    .deleteRealmIfMigrationNeeded()
                    .build()
    
            Realm.setDefaultConfiguration(config)
        }
    
        override fun onTerminate() {
            super.onTerminate()
            if (!Realm.getDefaultInstance().isClosed) {
                Realm.getDefaultInstance().close()
            }
        }
    }
    

    4.RealmHelper class

    class RealmHelper {
    
    var realm: Realm
        private set
    
    init {
        realm = try {
    
            Realm.getDefaultInstance()
    
        } catch (e: Exception) {
    
            Log.d("Realm Exception", e.toString())
    
            val config = RealmConfiguration.Builder()
                    .deleteRealmIfMigrationNeeded()
                    .build()
            Realm.getInstance(config)
        }
    }
    
    fun selectTables() {
        val parent = queryAll(ParentTable::class.java)
        Log.d("parent", parent.toString())
    
        parent?.forEach {
            it.child?.forEach {
                Log.d("parent.child", it.toString())
            }
        }
    
        val child = queryAll(ChildTable::class.java)
        Log.d("child", child.toString())
    
        child?.forEach {
            Log.d("child.parent", it.parent?.toString())
        }
    }
    
    fun insertParent() {
    
        val parent = ParentTable()
        parent.id = 1
        parent.parentname = "First Parent"
    
        val childList = RealmList<ChildTable>()
        val child = queryAll(ChildTable::class.java)
    
        child?.forEach {
            val child = ChildTable()
            child.id = it.id
            child.childName = it.childName
    
            childList.add(child)
        }
    
        parent.child = childList
    
        addRealmListData(parent)
    }
    
    
    fun insertChild() {
        val maxId = realm.where(ChildTable::class.java).max("id")
        val nextId : Long =
                when(maxId) {
                    null -> { 1 }
                    else -> { maxId.toLong() + 1 }
                }
    
        val parentId = realm.where(ParentTable::class.java).findFirst()
        val child = ChildTable()
        child.id = nextId
        child.childName = "child num : $nextId"
        child.parentId = parentId?.id
    
        addData(child)
    }
    
    //Insert To Realm
    fun <T : RealmObject> addData(data: T) {
        realm.executeTransaction {
            realm.copyToRealm(data)
        }
    }
    
    //Insert To Realm with RealmList
    fun <T : RealmObject> addRealmListData(data: T) {
        realm.executeTransaction {
            realm.copyToRealmOrUpdate(data)
        }
    }
    
    fun <T : RealmObject> queryAll(clazz: Class<T>): RealmResults<T>? {
        return realm.where(clazz).findAll()
    }
    
    companion object {
    
        private var INSTANCE: RealmHelper? = RealmHelper()
    
        val instance: RealmHelper
            get() {
                if (INSTANCE == null) {
                    INSTANCE = RealmHelper()
                }
                return INSTANCE as RealmHelper
            }
    }
    

    }

    5.MainActivity类

    class MainActivity : AppCompatActivity() {
    
    lateinit var compositeDisposable: CompositeDisposable
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    
        compositeDisposable = CompositeDisposable()
    
        initParentTable()
        setButtonClick()
    }
    
    private fun initParentTable() {
    
        val parentTable = RealmHelper.instance.queryAll(ParentTable::class.java)
    
        if (parentTable?.isEmpty()!!){
            RealmHelper.instance.insertParent()
        }
    
    }
    
    private fun setButtonClick() {
    
        btn_addchild.clicks()
                .subscribe {
                    RealmHelper.instance.insertChild()
                }.apply { compositeDisposable.add(this) }
    
        btn_parentquery.clicks()
                .subscribe {
                    RealmHelper.instance.selectTables()
                }.apply { compositeDisposable.add(this) }
    
    }
    
    override fun onDestroy() {
        compositeDisposable.clear()
        super.onDestroy()
    }
    

    }

    这是领域查询日志

    fun selectTables() {
        val parent = queryAll(ParentTable::class.java)
        Log.d("parent", parent.toString())
    
        parent?.forEach {
            it.child?.forEach {
                Log.d("parent.child", it.toString())
            }
        }
    
        val child = queryAll(ChildTable::class.java)
        Log.d("child", child.toString())
    
        child?.forEach {
            Log.d("child.parent", it.parent?.toString())
        }
    }
    

    点击addChild按钮三次,查询并查看结果

    03-26 12:22:17.534 29996-29996/com.hanmo.testforlinkingobject D/parent: [ParentTable = proxy[{id:1},{parentname:First Parent},{child:RealmList<ChildTable>[0]}]]
    03-26 12:22:17.535 29996-29996/com.hanmo.testforlinkingobject D/child: [ChildTable = proxy[{id:1},{parentId:1},{childName:child num : 1}], ChildTable = proxy[{id:2},{parentId:1},{childName:child num : 2}], ChildTable = proxy[{id:3},{parentId:1},{childName:child num : 3}]]
    03-26 12:22:17.536 29996-29996/com.hanmo.testforlinkingobject D/child.parent: []
    03-26 12:22:17.536 29996-29996/com.hanmo.testforlinkingobject D/child.parent: []
    03-26 12:22:17.537 29996-29996/com.hanmo.testforlinkingobject D/child.parent: []
    

    =&GT;父表和子表未链接。

    请如何在没有子表的情况下添加RealmList

2 个答案:

答案 0 :(得分:0)

  

如果在添加父表时没有子表,如何添加RealmList?

您需要Child课程才能添加RealmList<Child>

可以在事务中使用托管对象构建关系。

r.executeTransaction((realm) -> {
    ...
    Child child = realm.createObject(Child.class);
    Parent parent = realm.where(Parent.class)./*...*/.findFirst();
    parent.getChildren().add(child);
    ...
}
  

父表和子表之间是否存在实时链接?

  

如何迁移RealmList,@ LinkObject

使用realmObjectSchema.addRealmListField() method添加RealmList<T>

计算

@LinkingObjects而不是模式的一部分,因此不需要迁移。

答案 1 :(得分:0)

自应答

父表

open class ParentTable : RealmObject() {

    @PrimaryKey
    open var id: Long = 0

    open var parentName : String? = null

    var child: RealmList<ChildTable>? = RealmList()
}

儿童表

open class ChildTable : RealmObject() {

@PrimaryKey
open var id : Long = 0

open var childName : String? = null

open var parentName : String? = null

@LinkingObjects("child")
val parent: RealmResults<ParentTable>? = null

}

插入父数据

fun insertParent(parentName: String) {

    val maxId = realm.where(ParentTable::class.java).max("id")
    val nextId : Long =
            when(maxId) {
                null -> { 1 }
                else -> { maxId.toLong() + 1 }
            }

    val parent = ParentTable() // realm.createObject(Parent::class.java)
    parent.id = nextId
    parent.parentName = parentName

    addRealmListData(parent)

}

插入子数据

fun insertChild(childName: String, parentName: String) {
    val maxId = realm.where(ChildTable::class.java).max("id")
    val nextId : Long =
            when(maxId) {
                null -> { 1 }
                else -> { maxId.toLong() + 1 }
            }

    val child = ChildTable() //realm.createObject(ChildTable::class.java)
    child.id = nextId
    child.childName = childName
    child.parentName = parentName

    var parent = realm.where(ParentTable::class.java).equalTo("parentName", parentName).findFirst()

    realm.executeTransaction {
        parent?.child?.add(child)
        realm.copyToRealmOrUpdate(child)
    }
}

addRealmListData()

//Insert To Realm with RealmList
fun <T : RealmObject> addRealmListData(data: T) {
    realm.executeTransaction {
        realm.copyToRealmOrUpdate(data)
    }
}
  • 解决问题

When I put the data of the child table, I put the data by specifying the parent table.

我的示例代码:enter link description here