美文网首页
数据结构

数据结构

作者: 流沙无形 | 来源:发表于2019-05-27 10:09 被阅读0次

    家谱树数据结构

    1、家庭成员数据库表存储结构,代码使用room存储数据

    @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
    
        // 手机号
        @ColumnInfo(name = "phone")
        @SerializedName("phone")
        var phone: String? = null // 手机号
        
        ...
        
    }
    

    其中id作为数据库主键自增。而fatherId和spouseId与其他成员建立联系,因为在一个家族之中一个成员的父亲和配偶都是唯一的(不考虑离异情况),而成员的母亲节点可以以父亲的配偶来获得(一夫一妻的情况),以此自上而下形成家族树关系。

    2、家族树成员数据模型

    /**
     * 家族树数据模型
     * */
    data class FamilyMemberModel(var memberEntity: FamilyMemberEntity) {
    
        // 配偶
        var spouseEntity: FamilyMemberEntity? = null
    
        // 孩子
        var childModels: List<FamilyMemberModel>? = null
    
    }
    

    每个家族树成员包含三个成员:memberEntity、spouseEntity、childModels。其中memberEntity是当前成员的数据库信息,spouseEntity是当前成员配偶的信息,childModels是孩子的数据模型的集合。请注意childModels的类型是List<FamilyMemberModel>,也就是说childModels不仅包含孩子的基本信息,还包含孩子的配偶以及孩子的孩子信息。这是一种递归的表示方法,通过这种方法可以无限延伸下去。

    3、数据库操作

    @Dao
    interface BaseDao<T> {
    
        @Insert
        fun insertItem(item: T) //插入单条数据
    
        @Insert
        fun insertItems(items: List<T>) //插入list数据
    
        @Delete
        fun deleteItem(item: T) //删除item
    
        @Update
        fun updateItem(item: T) //更新item
    
    }
    
    @Dao
    interface FamilyMemberDao: BaseDao<FamilyMemberEntity> {
    
        /**
         * 根据id查询FamilyMemberEntity
         */
        @Query("SELECT * FROM members WHERE id = :id ")
        fun getMemberById(id: Long): FamilyMemberEntity
    
        /**
         * 根据id查询配偶信息
         */
        @Query("SELECT * FROM members WHERE spouseId = :spouseId ")
        fun getSpouseMemberById(spouseId: Long): FamilyMemberEntity
    
        /**
         * 根据id查询所有子FamilyMemberEntity集合
         */
        @Query("SELECT * FROM members WHERE fatherId = :id ")
        fun getChildMembers(id: Long): List<FamilyMemberEntity>
    
        /**
         * 查询全部结果
         */
        @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,会报FamilyDataBase_impl未生成的错误,不知道啥原因,使用java就好了。

    数据库操作工具类

    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!!
            }
        }
    
        /**
         * 根据id获取Member
         */
        fun getFamilyMember(id: Long): FamilyMemberEntity{
            return appDataBase.familyMemberDao().getMemberById(id)
        }
    
        /**
         * 根据id获取配偶Member
         */
        fun getSpouseMember(id: Long): FamilyMemberEntity{
            return appDataBase.familyMemberDao().getSpouseMemberById(id)
        }
    
        /**
         * 根据id获取子Member
         */
        fun getChildMembers(id: Long): List<FamilyMemberEntity> {
            return appDataBase.familyMemberDao().getChildMembers(id)
        }
    
        /**
         * 更新FamilyMemberEntity;必须在非主线程中进行
         */
        fun updateMember(member: FamilyMemberEntity) {
            appDataBase.familyMemberDao().updateItem(member)
        }
    
        /**
         * 插入FamilyMemberEntity;必须在非主线程中进行
         */
        fun insertMember(member: FamilyMemberEntity) {
            appDataBase.familyMemberDao().insertItem(member)
        }
    }
    

    3、生成家族树数据模型

    1. 获取家族树根节点
    var familyMember = FamilyDataBaseHelper.getInstance(this).getFamilyMember(1)
    

    在非主线程调用,demo里面数据库只有一个家族树,所以我用第一条作为整个树的根节点。实际情况可以在表中添加一个根节点的标记字段还获取根节点。

    2.通过跟节点生成家族树模型

    if (familyMember != null) {
        var familyMemberModel = familyMember.generateMember(this)
    }
    

    这里调用generateMember方法来生成数据模型,我们来看一下这个方法的源码

    /**
     * 将数据库数据转换成家族树成员模型
     * */
    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
    }
    

    其中当前节点的配偶通过查询数据库获得,获取孩子节点的getChildMembers方法里面会递归调用generateMember方法,从而延伸获取到整个家族树。

    4、我们来插入一些测试数据,看一下最后显示的效果。

    // 插入第一条数据,同时也是整个家族树的跟节点
    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条插入的数据,也就是上面的王根
    familyMember.sex = 1
    FamilyDataBaseHelper.getInstance(this).insertMember(familyMember)
    
    familyMember = FamilyMemberEntity("王芸")
    familyMember.imagePath = "222.jpg"
    familyMember.phone = "18156096666"
    familyMember.fatherId = 1 // 父亲id为1,表示其父亲未第1条插入的数据,也就是上面的王根
    familyMember.sex = 0
    FamilyDataBaseHelper.getInstance(this).insertMember(familyMember)
    
    familyMember = FamilyMemberEntity("王恩")
    familyMember.imagePath = "222.jpg"
    familyMember.phone = "18156096666"
    familyMember.fatherId = 2 // 父亲id为2,表示其父亲未第2条插入的数据,也就是上面的王明
    familyMember.sex = 0
    FamilyDataBaseHelper.getInstance(this).insertMember(familyMember)
    

    对应的家族树如下:


    familytre.jpg

    相关文章

      网友评论

          本文标题:数据结构

          本文链接:https://www.haomeiwen.com/subject/usjctctx.html