Kotlin Room使用指南:如何生成独立于用户主键的12-15位唯一公开ID
解决方案
一、12-15位唯一ID生成逻辑
移动端本地场景下可以用「时间戳后段+随机数」的方案,重复概率极低,完全满足本地使用需求,示例工具类如下:
object PublicIdGenerator { // 生成12-15位纯数字唯一ID fun generate(): String { // 取当前时间戳的后8位 val timePart = System.currentTimeMillis().toString().takeLast(8) // 随机生成4-7位数字,总长度12-15位 val randomLength = (4..7).random() val randomPart = (1..randomLength).joinToString("") { (0..9).random().toString() } return timePart + randomPart } }
如果需要包含字母的ID,可以把随机数部分换成数字+大小写字母的字符池即可。
二、Room层适配修改
1. 实体类加唯一约束
给userPublicId字段加唯一索引,避免极端情况下的ID重复,修改后的实体类如下:
@Entity( // 给对外公开ID加唯一约束,防止重复 indices = [Index(value = ["userPublicId"], unique = true)] ) data class UserInfo( @PrimaryKey(autoGenerate = true) val userId:Int = 0, val image: String, val imageSource : String,//Local or Online val username : String, val gender :String, // 插入时如果不传就自动生成 val userPublicId:String = PublicIdGenerator.generate(), val birthday : String, val userIntro :String, )
2. 插入数据异常处理
因为加了唯一约束,极端情况碰到ID重复时Room会抛出异常,插入时加个重试逻辑即可:
suspend fun insertUser(userInfo: UserInfo, retryCount: Int = 3): Long { repeat(retryCount) { try { return userDao.insertUser(userInfo) } catch (e: SQLiteConstraintException) { // 唯一约束冲突,重新生成ID再次插入 val newUser = userInfo.copy(userPublicId = PublicIdGenerator.generate()) return userDao.insertUser(newUser) } } throw RuntimeException("公开ID生成多次冲突,请检查生成逻辑") }
注意事项
- 如果你是单设备本地使用,上述方案完全够用,ID重复概率可以忽略不计
- 如果你的应用需要多端数据同步,建议公开ID由服务端统一生成返回,避免多端生成ID出现冲突
内容的提问来源于stack exchange,提问作者Yellow Clock
相关产品推荐
相关产品推荐

