gson Android房间数据关系

nnsrf1az  于 2022-11-06  发布在  Android
关注(0)|答案(1)|浏览(143)

在父类中有多个对象类型。假设我有一个如下的College类

data class College(
    @PrimaryKey
    val id:String,
    val name: String? = null,
    val description: String? = null,
    val groups: List<Group>? = null,
    val status: String? = null,
)

data class Group(
    @PrimaryKey
    val id:String,
    val name: String? = null,
    val description: String? = null,
    val students: List<Students>? = null,
)

这里的问题是在子表中没有关系id。我的意思是接收到的JSON没有给予大学内部团体与Groups表中collegeId的关系,也没有给出group表中学生的关系。
接收到的JSON如下

"college": [
{
  "id": "collegeid",
  "groups": [
    "id": "groupid"
    "name": "BCOM" // Here no collegeId  is mentioned inside it
  ]
}

如果使用@Embedded关键字,则会引发“实体和POJO必须具有可用的公共构造函数”。
有没有用上面的JSON,我可以设置组内大学的id,并将其作为关系的外键。
我已经使用了Typeconverters,并且运行良好,但是现在我需要使用上述JSON类型在这些表之间创建关系。
我使用Gson解析

mgdq6dx1

mgdq6dx11#

我相信您可能会混淆如何使用关系/表。

如果您有

@Entity
data class College(
    @PrimaryKey
    val id:String,
    val name: String? = null,
    val description: String? = null,
    val groups: List<Group>? = null,
    val status: String? = null,
)

这将是一个表,其中groups列(理论上)将包含一个组列表,没有关系,因为只有一个列包含单个数据流(可能是JSON字符串)。
但是,如果您希望有一个包含College的表、一个包含Groups的表和一个包含Students的表,则您不会将Groups嵌入到College中,然后将Students嵌入到Groups中。
相反,如果你想从数据库关系的Angular 来处理这个问题。假设一个组必须属于一个且只有一个学院,而一个学生必须只属于一个组,那么你会得到沿着的东西:-

@Entity
data class College(
    @PrimaryKey
    val id:String,
    val name: String? = null,
    val description: String? = null,
    //val groups: List<Group>? = null, //<<<<< NO NEED (see Group)
    val status: String? = null,
)

@Entity
data class Group(
    @PrimaryKey
    val id:String,
    val name: String? = null,
    val description: String? = null,
    //val students: List<Students>? = null, //<<<<< NO NEED (similar to Group)
    val collegeId: String //<<<<< ADDED for relationships to parent College
)
  • 与学生相似
  • 这里的关键因素是新的列/字段/变量collegeId,它应该包含父学院的id。

要获取包含相关组的学院,您可以创建一个类,其中父类(学院)具有@Embedded注解,子类(组)具有@Relation注解。例如:

data class CollegeWithRelatedGroups(
    @Embedded
    val college: College,
    @Relation(
        entity = Group::class,
        parentColumn = "id",
        entityColumn = "collegeId"
    )
    val groups: List<Group>
)

工作示例

下面是一个工作示例,使用上面的方法添加(插入)3个College,然后添加6个Group。第一个College有3个相关的Group,第二个有2个,第三个有1个。
然后,该示例提取Colleges和相关的Groups,并将结果输出到日志。

学院以及相关团体学院

@Entity
data class College(
    @PrimaryKey
    val id:String,
    val name: String? = null,
    val description: String? = null,
    //val groups: List<Group>? = null,
    val status: String? = null
)

data class CollegeWithRelatedGroups(
    @Embedded
    val college: College,
    @Relation(
        entity = Group::class,
        parentColumn = "id",
        entityColumn = "collegeId"
    )
    val groups: List<Group>
)

(具有外键约束)

@Entity(
    /* Optional but suggested Foreign Key to enforce referential integrity
     */
    foreignKeys = [
        ForeignKey(
            entity = College::class,
            parentColumns = ["id"],
            childColumns = ["collegeId"],
            /* Optional within Foreign Key - helps maintain referential integrity (if CASCADE)

                ON DELETE will delete the Groups that are related to a College if the College is deleted
                ON UPDATE will change the collegeId of Groups that are related to a College if the id of the College is changed
             */
            onDelete = ForeignKey.CASCADE,
            onUpdate = ForeignKey.CASCADE
        )
    ]
)
data class Group(
    @PrimaryKey
    val id:String,
    val name: String? = null,
    val description: String? = null,
    //val students: List<Student>? = null,
    @ColumnInfo(index = true) /* faster to access via relationship if indexed */
    val collegeId: String
)

天道

@Dao
interface AllDao {
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(college: College): Long
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(group: Group): Long
    @Transaction
    @Query("SELECT * FROM college")
    fun getCollegesWithRelatedGroups(): List<CollegeWithRelatedGroups>

}

TheDatabase(注意为简洁方便允许主线程处理)

@Database(entities = [College::class, Group::class], version = 1, exportSchema = false)
abstract class TheDatabase : RoomDatabase() {

    abstract fun getAllDao(): AllDao
    companion object {

        @Volatile
        private var instance: TheDatabase? = null
        fun getInstance(context: Context): TheDatabase {
            if (instance == null) {
                instance = Room.databaseBuilder(context, TheDatabase::class.java, "the_database.db")
                    .allowMainThreadQueries()
                    .build()
            }
            return instance as TheDatabase
        }
    }
}
  • 请注意,不需要TypeConverter,因为不存储对象(即存储简单类型)
    活动代码(本例中为MainActivity)
const val TAG = "DBINFO"
class MainActivity : AppCompatActivity() {
    lateinit var db: TheDatabase
    lateinit var dao: AllDao
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        db = TheDatabase.getInstance(this)
        dao = db.getAllDao()

        dao.insert(College("College1","The first College","Opened"))
        dao.insert(College("College2","The second College","Opened"))
        dao.insert(College("New College","A new College","Being built"))

        dao.insert(Group("GroupA","Group A or something","The first Group - hence A","College1",))
        dao.insert(Group("GroupB","Group B or whatever"," The second Group ...", "College2"))
        dao.insert(Group("GroupC","Group C on so on","The third Group ...","New College"))
        dao.insert(Group("GroupX","Group X ...","The Xth group","College1"))
        dao.insert(Group("GroupY","...","...","College1"))
        dao.insert(Group("GroupZ","...","...","College2"))

        for (cwrg in dao.getCollegesWithRelatedGroups()) {
            Log.d(TAG,"College is ID=${cwrg.college.id} Desc=${cwrg.college.description} Name=${cwrg.college.name} Status=${cwrg.college.name}\nIt has ${cwrg.groups.size} Groups. They are:-")
            for (g in cwrg.groups) {
                Log.d(TAG,"\n\t\tGroup is ID=${g.id} Name=${g.name} Desc=${g.description} it reference CollegeID=${g.collegeId}")
            }
        }
    }
}

*尚未提供学院的状态,因此它们将为空。
结果日志包括:-

D/DBINFO: College is ID=College1 Desc=Opened Name=The first College Status=The first College
    It has 3 Groups. They are:-
D/DBINFO:       Group is ID=GroupA Name=Group A or something Desc=The first Group - hence A it reference CollegeID=College1
D/DBINFO:       Group is ID=GroupX Name=Group X ... Desc=The Xth group it reference CollegeID=College1
D/DBINFO:       Group is ID=GroupY Name=... Desc=... it reference CollegeID=College1

D/DBINFO: College is ID=College2 Desc=Opened Name=The second College Status=The second College
    It has 2 Groups. They are:-
D/DBINFO:       Group is ID=GroupB Name=Group B or whatever Desc= The second Group ... it reference CollegeID=College2
D/DBINFO:       Group is ID=GroupZ Name=... Desc=... it reference CollegeID=College2

D/DBINFO: College is ID=New College Desc=Being built Name=A new College Status=A new College
    It has 1 Groups. They are:-
D/DBINFO:       Group is ID=GroupC Name=Group C on so on Desc=The third Group ... it reference CollegeID=New College

通过应用程序检查的数据库:-

相关问题