我可以在房间数据库中自动增加 id 但是当刷新数据库时它显示双倍
I can auto increment id in room database but when refresh database it's shows double
在我的应用程序中,我首先使用改造从服务器获取数据,然后将其保存在房间数据库中 table 然后它显示在 recyclerview 中,但是当我使用 id 作为主键时,它只显示一个数据然后这个id i annotat autoGenerate = true 然后它显示我放入服务器的所有数据但是当我重新打开我的应用程序时,它显示双重数据(这意味着首先我在服务器中有 3 个数据,这个应用程序显示 3 个数据但是当我重新打开或刷新我的数据库它显示 6 个数据,每次刷新它都在增加)。但我希望这个 ID 会增加但数据不会增加这意味着服务器有 3 个数据并且它存储在房间数据库 table.
Movie.kt
@Entity(tableName = "movie_table")
data class Movie(
@PrimaryKey(autoGenerate = true)
var id: Int = 0,
@SerializedName("Title")
@Expose
val title: String,
@SerializedName("Year")
@Expose
val Year: Int,
@SerializedName("Genre")
@Expose
val genre: String,
@SerializedName("Language")
@Expose
val language: String,
@SerializedName("Country")
@Expose
val country: String,
@SerializedName("Poster")
@Expose
val poster: String,
@SerializedName("Plot")
@Expose
val plot:String
)
MovieDao.kt
@Dao
interface MovieDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertMovie(movie: Movie)
@Query("SELECT * FROM movie_table")
suspend fun getAllMovieDB(): List<Movie>
@Query("SELECT * FROM movie_table WHERE title LIKE :title")
suspend fun getSearchMovieDB(title: String): List<Movie>
}
MovieDatabase.kt
@Database(
entities = [Movie::class],
version = 1)
abstract class MovieDatabase: RoomDatabase() {
abstract fun getMovieDao(): MovieDao
companion object{
@Volatile
private var instance : MovieDatabase? = null
private val LOCK = Any()
operator fun invoke(context: Context) = instance
?: synchronized(LOCK){
instance
?: buildDatabase(context).also{
instance = it
}
}
private fun buildDatabase(context: Context) = Room.databaseBuilder(
context.applicationContext,
MovieDatabase::class.java,
"movieDatabase"
).build()
}
}
Repository.kt
class Repository(context: Context) {
private val movieDao: MovieDao = MovieDatabase.invoke(context).getMovieDao()
private val movieCall = MovieApiClient.movieApi
suspend fun insertMovie(movie: Movie) {
movieDao.insertMovie(movie)
}
suspend fun searchData(title: String): List<Movie> {
return movieDao.getSearchMovieDB(title)
}
suspend fun getAllMovieDB(): List<Movie> {
return movieDao.getAllMovieDB().also {
getAllMovieFromServer()
}
}
private suspend fun getAllMovieFromServer() {
try {
val movieList = movieCall.getAllMovie()
movieList.forEach {
insertMovie(it)
}
} catch (exception: Throwable) {
}
}
}
更好地理解图像
(1)当id为主键时不用"autoGenerate = true"注解
enter image description here
(2)当id为主键时用"autoGenerate = true"注解
enter image description here
如何在没有双重数据的情况下增加 id,我该如何解决这个问题?请帮助我,谢谢。
您似乎没有从服务器获取电影 ID。
这意味着您无法知道特定电影何时已存在于您的数据库中,这就是它“重复”的原因。
要解决此问题,只需确保也从服务器获取电影 ID 以及所有其他电影数据。
并删除“autoGenerate = true”,因为您将使用自己的 ID。
这将确保当从服务器获取您的数据库中已存在的电影时,插入查询中会发生冲突,并且由于您使用了“(onConflict = OnConflictStrategy.REPLACE)”它将用新数据更新行。
在我的应用程序中,我首先使用改造从服务器获取数据,然后将其保存在房间数据库中 table 然后它显示在 recyclerview 中,但是当我使用 id 作为主键时,它只显示一个数据然后这个id i annotat autoGenerate = true 然后它显示我放入服务器的所有数据但是当我重新打开我的应用程序时,它显示双重数据(这意味着首先我在服务器中有 3 个数据,这个应用程序显示 3 个数据但是当我重新打开或刷新我的数据库它显示 6 个数据,每次刷新它都在增加)。但我希望这个 ID 会增加但数据不会增加这意味着服务器有 3 个数据并且它存储在房间数据库 table.
Movie.kt
@Entity(tableName = "movie_table")
data class Movie(
@PrimaryKey(autoGenerate = true)
var id: Int = 0,
@SerializedName("Title")
@Expose
val title: String,
@SerializedName("Year")
@Expose
val Year: Int,
@SerializedName("Genre")
@Expose
val genre: String,
@SerializedName("Language")
@Expose
val language: String,
@SerializedName("Country")
@Expose
val country: String,
@SerializedName("Poster")
@Expose
val poster: String,
@SerializedName("Plot")
@Expose
val plot:String
)
MovieDao.kt
@Dao
interface MovieDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertMovie(movie: Movie)
@Query("SELECT * FROM movie_table")
suspend fun getAllMovieDB(): List<Movie>
@Query("SELECT * FROM movie_table WHERE title LIKE :title")
suspend fun getSearchMovieDB(title: String): List<Movie>
}
MovieDatabase.kt
@Database(
entities = [Movie::class],
version = 1)
abstract class MovieDatabase: RoomDatabase() {
abstract fun getMovieDao(): MovieDao
companion object{
@Volatile
private var instance : MovieDatabase? = null
private val LOCK = Any()
operator fun invoke(context: Context) = instance
?: synchronized(LOCK){
instance
?: buildDatabase(context).also{
instance = it
}
}
private fun buildDatabase(context: Context) = Room.databaseBuilder(
context.applicationContext,
MovieDatabase::class.java,
"movieDatabase"
).build()
}
}
Repository.kt
class Repository(context: Context) {
private val movieDao: MovieDao = MovieDatabase.invoke(context).getMovieDao()
private val movieCall = MovieApiClient.movieApi
suspend fun insertMovie(movie: Movie) {
movieDao.insertMovie(movie)
}
suspend fun searchData(title: String): List<Movie> {
return movieDao.getSearchMovieDB(title)
}
suspend fun getAllMovieDB(): List<Movie> {
return movieDao.getAllMovieDB().also {
getAllMovieFromServer()
}
}
private suspend fun getAllMovieFromServer() {
try {
val movieList = movieCall.getAllMovie()
movieList.forEach {
insertMovie(it)
}
} catch (exception: Throwable) {
}
}
}
更好地理解图像 (1)当id为主键时不用"autoGenerate = true"注解 enter image description here
(2)当id为主键时用"autoGenerate = true"注解 enter image description here
如何在没有双重数据的情况下增加 id,我该如何解决这个问题?请帮助我,谢谢。
您似乎没有从服务器获取电影 ID。 这意味着您无法知道特定电影何时已存在于您的数据库中,这就是它“重复”的原因。
要解决此问题,只需确保也从服务器获取电影 ID 以及所有其他电影数据。 并删除“autoGenerate = true”,因为您将使用自己的 ID。
这将确保当从服务器获取您的数据库中已存在的电影时,插入查询中会发生冲突,并且由于您使用了“(onConflict = OnConflictStrategy.REPLACE)”它将用新数据更新行。