家譜樹數(shù)據(jù)結(jié)構(gòu)
1预鬓、家庭成員數(shù)據(jù)庫表存儲(chǔ)結(jié)構(gòu)船庇,代碼使用room存儲(chǔ)數(shù)據(jù)
@Entity(tableName = "members")
data class FamilyMemberEntity(var name: String) {
constructor() : this("")
// 主鍵自增
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
@SerializedName("id")
var id: Long = 0
// 父親id
@ColumnInfo(name = "fatherId")
@SerializedName("fatherId")
var fatherId: Long? = null
// 配偶id
@ColumnInfo(name = "spouseId")
@SerializedName("spouseId")
var spouseId: Long? = null
// 性別
@ColumnInfo(name = "sex")
@SerializedName("sex")
var sex: Int = 0
// 手機(jī)號(hào)
@ColumnInfo(name = "phone")
@SerializedName("phone")
var phone: String? = null // 手機(jī)號(hào)
...
}
其中id作為數(shù)據(jù)庫主鍵自增。而fatherId和spouseId與其他成員建立聯(lián)系个从,因?yàn)樵谝粋€(gè)家族之中一個(gè)成員的父親和配偶都是唯一的(不考慮離異情況)脉幢,而成員的母親節(jié)點(diǎn)可以以父親的配偶來獲得(一夫一妻的情況),以此自上而下形成家族樹關(guān)系嗦锐。
2嫌松、家族樹成員數(shù)據(jù)模型
/**
* 家族樹數(shù)據(jù)模型
* */
data class FamilyMemberModel(var memberEntity: FamilyMemberEntity) {
// 配偶
var spouseEntity: FamilyMemberEntity? = null
// 孩子
var childModels: List<FamilyMemberModel>? = null
}
每個(gè)家族樹成員包含三個(gè)成員:memberEntity、spouseEntity奕污、childModels萎羔。其中memberEntity是當(dāng)前成員的數(shù)據(jù)庫信息,spouseEntity是當(dāng)前成員配偶的信息碳默,childModels是孩子的數(shù)據(jù)模型的集合贾陷。請(qǐng)注意childModels的類型是List<FamilyMemberModel>缘眶,也就是說childModels不僅包含孩子的基本信息,還包含孩子的配偶以及孩子的孩子信息髓废。這是一種遞歸的表示方法巷懈,通過這種方法可以無限延伸下去。
3慌洪、數(shù)據(jù)庫操作
@Dao
interface BaseDao<T> {
@Insert
fun insertItem(item: T) //插入單條數(shù)據(jù)
@Insert
fun insertItems(items: List<T>) //插入list數(shù)據(jù)
@Delete
fun deleteItem(item: T) //刪除item
@Update
fun updateItem(item: T) //更新item
}
@Dao
interface FamilyMemberDao: BaseDao<FamilyMemberEntity> {
/**
* 根據(jù)id查詢FamilyMemberEntity
*/
@Query("SELECT * FROM members WHERE id = :id ")
fun getMemberById(id: Long): FamilyMemberEntity
/**
* 根據(jù)id查詢配偶信息
*/
@Query("SELECT * FROM members WHERE spouseId = :spouseId ")
fun getSpouseMemberById(spouseId: Long): FamilyMemberEntity
/**
* 根據(jù)id查詢所有子FamilyMemberEntity集合
*/
@Query("SELECT * FROM members WHERE fatherId = :id ")
fun getChildMembers(id: Long): List<FamilyMemberEntity>
/**
* 查詢?nèi)拷Y(jié)果
*/
@Query("SELECT * FROM members")
fun getAllMembers(): List<FamilyMemberEntity>
}
繼承RoomDatabase
@Database(entities = {FamilyMemberEntity.class}, version = 1)
abstract public class FamilyDataBase extends RoomDatabase {
public abstract FamilyMemberDao familyMemberDao();
}
這段代碼使用java編寫顶燕,之前使用kotlin,會(huì)報(bào)FamilyDataBase_impl未生成的錯(cuò)誤冈爹,不知道啥原因割岛,使用java就好了。
數(shù)據(jù)庫操作工具類
class FamilyDataBaseHelper constructor(context: Context) {
private val appDataBase = Room.databaseBuilder(context, FamilyDataBase::class.java,
"family.db").build()!!
companion object {
@Volatile
var INSTANCE: FamilyDataBaseHelper? = null
fun getInstance(context: Context): FamilyDataBaseHelper {
if (INSTANCE == null) {
synchronized(FamilyDataBaseHelper::class) {
if (INSTANCE == null) {
INSTANCE = FamilyDataBaseHelper(context.applicationContext)
}
}
}
return INSTANCE!!
}
}
/**
* 根據(jù)id獲取Member
*/
fun getFamilyMember(id: Long): FamilyMemberEntity{
return appDataBase.familyMemberDao().getMemberById(id)
}
/**
* 根據(jù)id獲取配偶Member
*/
fun getSpouseMember(id: Long): FamilyMemberEntity{
return appDataBase.familyMemberDao().getSpouseMemberById(id)
}
/**
* 根據(jù)id獲取子Member
*/
fun getChildMembers(id: Long): List<FamilyMemberEntity> {
return appDataBase.familyMemberDao().getChildMembers(id)
}
/**
* 更新FamilyMemberEntity;必須在非主線程中進(jìn)行
*/
fun updateMember(member: FamilyMemberEntity) {
appDataBase.familyMemberDao().updateItem(member)
}
/**
* 插入FamilyMemberEntity;必須在非主線程中進(jìn)行
*/
fun insertMember(member: FamilyMemberEntity) {
appDataBase.familyMemberDao().insertItem(member)
}
}
3犯助、生成家族樹數(shù)據(jù)模型
- 獲取家族樹根節(jié)點(diǎn)
var familyMember = FamilyDataBaseHelper.getInstance(this).getFamilyMember(1)
在非主線程調(diào)用癣漆,demo里面數(shù)據(jù)庫只有一個(gè)家族樹,所以我用第一條作為整個(gè)樹的根節(jié)點(diǎn)剂买。實(shí)際情況可以在表中添加一個(gè)根節(jié)點(diǎn)的標(biāo)記字段還獲取根節(jié)點(diǎn)惠爽。
2.通過跟節(jié)點(diǎn)生成家族樹模型
if (familyMember != null) {
var familyMemberModel = familyMember.generateMember(this)
}
這里調(diào)用generateMember方法來生成數(shù)據(jù)模型,我們來看一下這個(gè)方法的源碼
/**
* 將數(shù)據(jù)庫數(shù)據(jù)轉(zhuǎn)換成家族樹成員模型
* */
fun generateMember(context: Context) : FamilyMemberModel {
var familyMemberModel = FamilyMemberModel(this)
familyMemberModel.spouseEntity = FamilyDataBaseHelper.getInstance(context).getSpouseMember(id)
familyMemberModel.childModels = getChildMembers(context)
return familyMemberModel
}
private fun getChildMembers(context: Context): List<FamilyMemberModel> {
var memberList = FamilyDataBaseHelper.getInstance(context).getChildMembers(id)
var memberModelList = ArrayList<FamilyMemberModel>()
for (member in memberList) {
memberModelList.add(member.generateMember(context))
}
return memberModelList
}
其中當(dāng)前節(jié)點(diǎn)的配偶通過查詢數(shù)據(jù)庫獲得瞬哼,獲取孩子節(jié)點(diǎn)的getChildMembers方法里面會(huì)遞歸調(diào)用generateMember方法婚肆,從而延伸獲取到整個(gè)家族樹。
4坐慰、我們來插入一些測(cè)試數(shù)據(jù)较性,看一下最后顯示的效果。
// 插入第一條數(shù)據(jù)结胀,同時(shí)也是整個(gè)家族樹的跟節(jié)點(diǎn)
var familyMember = FamilyMemberEntity("王根")
familyMember.imagePath = "111.jpg"
familyMember.phone = "18156094171"
familyMember.sex = 1
FamilyDataBaseHelper.getInstance(this).insertMember(familyMember)
familyMember = FamilyMemberEntity("王明")
familyMember.imagePath = "222.jpg"
familyMember.phone = "18156096666"
familyMember.fatherId = 1 // 父親id為1赞咙,表示其父親未第1條插入的數(shù)據(jù),也就是上面的王根
familyMember.sex = 1
FamilyDataBaseHelper.getInstance(this).insertMember(familyMember)
familyMember = FamilyMemberEntity("王蕓")
familyMember.imagePath = "222.jpg"
familyMember.phone = "18156096666"
familyMember.fatherId = 1 // 父親id為1糟港,表示其父親未第1條插入的數(shù)據(jù)攀操,也就是上面的王根
familyMember.sex = 0
FamilyDataBaseHelper.getInstance(this).insertMember(familyMember)
familyMember = FamilyMemberEntity("王恩")
familyMember.imagePath = "222.jpg"
familyMember.phone = "18156096666"
familyMember.fatherId = 2 // 父親id為2,表示其父親未第2條插入的數(shù)據(jù)秸抚,也就是上面的王明
familyMember.sex = 0
FamilyDataBaseHelper.getInstance(this).insertMember(familyMember)
對(duì)應(yīng)的家族樹如下: