为什么作者用 Android Jetpack 在 Room 的两个位置定义 table 字段?
Why does the author define the table fields in two position in Room with Android Jetpack?
我正在学习 Android Jetpack,以下代码来自 https://github.com/android/sunflower.
的示例项目
GardenPlanting.kt代码是设计了一个table,我很奇怪为什么作者把table字段定义在两个位置,你看@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id")
位于class.
的内部
我觉得Code B很容易理解吧?
GardenPlanting.kt
@Entity(
tableName = "garden_plantings",
foreignKeys = [
ForeignKey(entity = Plant::class, parentColumns = ["id"], childColumns = ["plant_id"])
],
indices = [Index("plant_id")]
)
data class GardenPlanting(
@ColumnInfo(name = "plant_id") val plantId: String,
@ColumnInfo(name = "plant_date") val plantDate: Calendar = Calendar.getInstance(),
@ColumnInfo(name = "last_watering_date")
val lastWateringDate: Calendar = Calendar.getInstance()
) {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
var gardenPlantingId: Long = 0
}
代码B
data class GardenPlanting(
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: String,
@ColumnInfo(name = "plant_id") val plantId: String,
@ColumnInfo(name = "plant_date") val plantDate: Calendar = Calendar.getInstance(),
@ColumnInfo(name = "last_watering_date")
val lastWateringDate: Calendar = Calendar.getInstance()
) {
var gardenPlantingId: Long = 0
}
data
class 构造函数中 属性 的声明用于:
- 生成component 函数用于析构
- 在
toString()
、equals()
、hashCode()
和 copy()
中使用这些字段
因此,如果您想避免使用 copy
方法复制字段,那么简单的方法是在 class.
的正文中声明字段
示例:
fun main() {
val user = User("Pavneet", "29k+")
user.id = kotlin.random.Random.nextInt(10, 20)
val userCopy = user.copy()
println(userCopy) // id won't be printed 'cuz it's not a part of toString method
userCopy.id = 99
print(userCopy.equals(user)) // true, 'cuz id is not being used by the equals method
//var(name, repo, id) = userCopy // error, User must have a 'component3()' function
var(name, repo) = userCopy
}
data class User(val name: String = "", val repo:String="0"){
var id:Int = 0
}
优点:
- 创建不包括特定字段的对象的副本
- 排除特定字段以比较两个对象是否相等
- 在解构声明中排除特定字段
注意:copy
和 component
方法不能明确提供(内部数据 class)。在示例 B 中,gardenPlantingId
被替换为 id
,因此可以删除。
答案很简单:
因为在此示例代码中,作者想表明我们可以对实体中的 ANY 成员使用 @PrimaryKey
和 @ColumnInfo
注释 class,不管它的位置如何(可以在构造函数内部,也可以在构造函数外部)。
要对此进行试验,您只需完全按照在 代码 B 上所做的操作即可。它也是有效的,但在那种情况下,gardenPlantingId
将没有自定义列名,因为我们不使用 @ColumnInfo
注释。此外,没有必要在构造函数外部声明 @PrimaryKey
(如给定的示例)。您可以在构造函数中声明主键注释。
我正在学习 Android Jetpack,以下代码来自 https://github.com/android/sunflower.
的示例项目GardenPlanting.kt代码是设计了一个table,我很奇怪为什么作者把table字段定义在两个位置,你看@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id")
位于class.
我觉得Code B很容易理解吧?
GardenPlanting.kt
@Entity(
tableName = "garden_plantings",
foreignKeys = [
ForeignKey(entity = Plant::class, parentColumns = ["id"], childColumns = ["plant_id"])
],
indices = [Index("plant_id")]
)
data class GardenPlanting(
@ColumnInfo(name = "plant_id") val plantId: String,
@ColumnInfo(name = "plant_date") val plantDate: Calendar = Calendar.getInstance(),
@ColumnInfo(name = "last_watering_date")
val lastWateringDate: Calendar = Calendar.getInstance()
) {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
var gardenPlantingId: Long = 0
}
代码B
data class GardenPlanting(
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: String,
@ColumnInfo(name = "plant_id") val plantId: String,
@ColumnInfo(name = "plant_date") val plantDate: Calendar = Calendar.getInstance(),
@ColumnInfo(name = "last_watering_date")
val lastWateringDate: Calendar = Calendar.getInstance()
) {
var gardenPlantingId: Long = 0
}
data
class 构造函数中 属性 的声明用于:
- 生成component 函数用于析构
- 在
toString()
、equals()
、hashCode()
和copy()
中使用这些字段
因此,如果您想避免使用 copy
方法复制字段,那么简单的方法是在 class.
示例:
fun main() {
val user = User("Pavneet", "29k+")
user.id = kotlin.random.Random.nextInt(10, 20)
val userCopy = user.copy()
println(userCopy) // id won't be printed 'cuz it's not a part of toString method
userCopy.id = 99
print(userCopy.equals(user)) // true, 'cuz id is not being used by the equals method
//var(name, repo, id) = userCopy // error, User must have a 'component3()' function
var(name, repo) = userCopy
}
data class User(val name: String = "", val repo:String="0"){
var id:Int = 0
}
优点:
- 创建不包括特定字段的对象的副本
- 排除特定字段以比较两个对象是否相等
- 在解构声明中排除特定字段
注意:copy
和 component
方法不能明确提供(内部数据 class)。在示例 B 中,gardenPlantingId
被替换为 id
,因此可以删除。
答案很简单:
因为在此示例代码中,作者想表明我们可以对实体中的 ANY 成员使用 @PrimaryKey
和 @ColumnInfo
注释 class,不管它的位置如何(可以在构造函数内部,也可以在构造函数外部)。
要对此进行试验,您只需完全按照在 代码 B 上所做的操作即可。它也是有效的,但在那种情况下,gardenPlantingId
将没有自定义列名,因为我们不使用 @ColumnInfo
注释。此外,没有必要在构造函数外部声明 @PrimaryKey
(如给定的示例)。您可以在构造函数中声明主键注释。