I would like to make a relationship like SQLite using Realm.
- If don't have a child table when add a parent table, how do add RealmList?
- Is there a real-time link between the parent table and the child table?
- How to migration RealmList, @LinkingObject
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
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()
}
}
this is realm query log
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())
}
}
Click on addChild button three times, query, and see results
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: []
=> Parent Table and Child Table are not linked.
please How to add a RealmList when there is no Child Table