Kotlin 数据类、Android Room 和自定义设置器
Posted
技术标签:
【中文标题】Kotlin 数据类、Android Room 和自定义设置器【英文标题】:Kotlin's data class, Android Room and custom setter 【发布时间】:2017-12-10 16:56:08 【问题描述】:我得到了一个看起来像这样的 android Room 实体。到目前为止,不用担心。
@Entity(tableName = "users",
indices = arrayOf(Index(value = "nickName", unique = true)))
data class User(@ColumnInfo(name = "nickName") var nickName: String,
@ColumnInfo(name = "password") var password: String)
@ColumnInfo(name = "id")
@PrimaryKey(autoGenerate = true)
var id: Long = 0
现在我需要加密密码。使用 Java,只需使用 setter 即可完成此操作。
您将如何使用 Kotlin 来做到这一点。我找不到将 Android Room、自定义设置器和数据类结合起来的解决方案。
【问题讨论】:
为什么不能覆盖值的设置器? 您的问题不清楚。 “使用 Java,只需使用 setter 即可完成此操作,这样就可以了。” - Kotlin 的可变属性有什么问题? @Egor 你如何为数据类做到这一点?通过私人_password
字段?在这种情况下,你在哪里连接@ColumnInfo?
@VincentMimoun-Prat 我想从设计的角度来看,在 setter 方法中编码密码不是正确的方法,只需在外部编码然后传递给模型
您可能有兴趣知道最佳做法是不存储密码,而是存储密码的盐和散列。例如见jasypt.org/howtoencryptuserpasswords.html。
【参考方案1】:
你可以试试这样的:
@Entity(tableName = "users",
indices = arrayOf(Index(value = "nickName", unique = true)))
data class User(@ColumnInfo(name = "nickName") var nickName: String,
private var _password: String)
@ColumnInfo(name = "id")
@PrimaryKey(autoGenerate = true)
var id: Long = 0
@ColumnInfo(name = "password")
var password: String = _password
set(value)
field = "encrypted"
override fun toString(): String
return "User(id=$id, nickName='$nickName', password='$password')"
但我不建议在 Entity 中加密密码或以某种方式修改密码,因为这不是它的责任,而且你可能会遇到密码双重加密的错误,因为当你从数据库中检索实体时,Room 会用数据填充实体这将导致加密已经加密的数据。
【讨论】:
这会解决问题,但现在表中必须有两列,“_password”和“password”。我还尝试用@Ignore 注释“_password”,但 ROOM 无法编译。有什么建议吗? @DariushMalek,正如我在答案中所写 - 我不推荐这种方法,最好对数据类的数据进行任何操作,仅将其用作获取和设置的容器数据。【参考方案2】: @Entity(tableName = "users",
indices = arrayOf(Index(value = "nickName", unique = true)))
data class User(@ColumnInfo(name = "nickName") var nickName: String,
@ColumnInfo(name = "password") var password: String)
var _password = password
set(value): String
//encrypt password
@ColumnInfo(name = "id")
@PrimaryKey(autoGenerate = true)
var id: Long = 0
这将创建一个自定义设置器,因此每次设置密码时,您都可以在设置器内对其进行加密。
【讨论】:
甚至没有编译 导致IDE编译错误:“overload resolution ambiguous” Getter 和 setter 可以在数据类中调用自定义,但您必须为它创建一个新变量。所以变量“密码”需要被称为别的东西。例如_密码以上是关于Kotlin 数据类、Android Room 和自定义设置器的主要内容,如果未能解决你的问题,请参考以下文章