數(shù)據(jù)結(jié)構(gòu)

家譜樹數(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ù)模型

  1. 獲取家族樹根節(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)的家族樹如下:


familytre.jpg
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末速和,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子剥汤,更是在濱河造成了極大的恐慌颠放,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吭敢,死亡現(xiàn)場(chǎng)離奇詭異碰凶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門痒留,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蠢沿,你說我怎么就攤上這事伸头。” “怎么了舷蟀?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵恤磷,是天一觀的道長。 經(jīng)常有香客問我野宜,道長扫步,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任匈子,我火速辦了婚禮河胎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘虎敦。我一直安慰自己游岳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布其徙。 她就那樣靜靜地躺著胚迫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪唾那。 梳的紋絲不亂的頭發(fā)上访锻,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音闹获,去河邊找鬼期犬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛避诽,可吹牛的內(nèi)容都是我干的哭懈。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼茎用,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼遣总!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起轨功,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤旭斥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后古涧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垂券,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了菇爪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片算芯。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖凳宙,靈堂內(nèi)的尸體忽然破棺而出熙揍,到底是詐尸還是另有隱情,我是刑警寧澤氏涩,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布届囚,位于F島的核電站,受9級(jí)特大地震影響是尖,放射性物質(zhì)發(fā)生泄漏意系。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一饺汹、第九天 我趴在偏房一處隱蔽的房頂上張望蛔添。 院中可真熱鬧,春花似錦兜辞、人聲如沸作郭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夹攒。三九已至,卻和暖如春胁塞,著一層夾襖步出監(jiān)牢的瞬間咏尝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工啸罢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留编检,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓扰才,卻偏偏與公主長得像允懂,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子衩匣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容