英文:
Unable to create a database using room in android
问题
我正在尝试使用Room创建一个用于存储单词卡片的数据库。我确信我已经完成了所有必要的代码,但是当我运行我的应用程序并使用Database Inspector时,它显示没有可显示的内容。我不确定为什么。
实体
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "flashcards")
data class Flashcard(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val question: String,
val answer: String
)
数据访问对象(DAO)
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import kotlinx.coroutines.flow.Flow
@Dao
interface FlashcardDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(flashcard: Flashcard)
@Update
suspend fun update(flashcard: Flashcard)
@Delete
suspend fun delete(flashcard: Flashcard)
@Query("SELECT * FROM flashcards WHERE id = :id")
fun getFlashcard(id: Int): Flow<Flashcard>
@Query("SELECT * FROM flashcards")
fun getAllFlashcards(): Flow<List<Flashcard>>
}
数据库类
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(
entities = [Flashcard::class],
version = 1,
exportSchema = false
)
abstract class FlashcardDatabase: RoomDatabase() {
abstract fun flashcardDao(): FlashcardDao
companion object {
@Volatile
private var Instance: FlashcardDatabase? = null
fun getDatabase(context: Context): FlashcardDatabase {
return Instance ?: synchronized(this) {
Room.databaseBuilder(context, FlashcardDatabase::class.java, "flashcard_database")
.fallbackToDestructiveMigration()
.build()
.also { Instance = it }
}
}
}
}
仓库接口
interface FlashCardsRepository {
fun getAllFlashcardsStream(): Flow<List<Flashcard>>
fun getFlashcardStream(id: Int): Flow<Flashcard?>
suspend fun insertFlashcard(flashcard: Flashcard)
suspend fun deleteFlashcard(flashcard: Flashcard)
suspend fun updateFlashcard(flashcard: Flashcard)
}
仓库实现类
import kotlinx.coroutines.flow.Flow
class OfflineFlashcardsRepository(private val flashcardDao: FlashcardDao) : FlashCardsRepository {
override fun getAllFlashcardsStream(): Flow<List<Flashcard>> = flashcardDao.getAllFlashcards()
override fun getFlashcardStream(id: Int): Flow<Flashcard?> = flashcardDao.getFlashcard(id)
override suspend fun insertFlashcard(flashcard: Flashcard) = flashcardDao.insert(flashcard = flashcard)
override suspend fun updateFlashcard(flashcard: Flashcard) = flashcardDao.update(flashcard = flashcard)
override suspend fun deleteFlashcard(flashcard: Flashcard) = flashcardDao.delete(flashcard = flashcard)
}
应用容器(用于依赖注入)
import android.content.Context
interface AppContainer {
val flashCardsRepository: FlashCardsRepository
}
class AppDataContainer(private val context: Context): AppContainer {
override val flashCardsRepository: FlashCardsRepository by lazy {
OfflineFlashcardsRepository(FlashcardDatabase.getDatabase(context).flashcardDao())
}
}
创建数据库实例的Flashcard应用程序的onCreate()方法(我已经将此应用程序添加到清单文件中)
import android.app.Application
import com.example.flashcardapp.data.AppContainer
import com.example.flashcardapp.data.AppDataContainer
class FlashcardApplication: Application() {
lateinit var container: AppContainer
override fun onCreate() {
super.onCreate()
container = AppDataContainer(this)
}
}
清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".FlashcardApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.FlashcardApp"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.FlashcardApp">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
英文:
I am trying to create a database to store flashcards using Room. I'm sure I have completed all the necessary code, however, when I run my application and use the Database Inspector, it says that there is nothing to show. I'm not sure why.
Entity
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "flashcards")
data class Flashcard(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val question: String,
val answer: String
)
Data Access Objects
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import kotlinx.coroutines.flow.Flow
@Dao
interface FlashcardDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(flashcard: Flashcard)
@Update
suspend fun update(flashcard: Flashcard)
@Delete
suspend fun delete(flashcard: Flashcard)
@Query("SELECT * FROM flashcards WHERE id = :id")
fun getFlashcard(id: Int): Flow<Flashcard>
@Query("SELECT * FROM flashcards")
fun getAllFlashcards(): Flow<List<Flashcard>>
}
Database Class
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(
entities = [Flashcard::class],
version = 1,
exportSchema = false
)
abstract class FlashcardDatabase: RoomDatabase() {
abstract fun flashcardDao(): FlashcardDao
companion object {
@Volatile
private var Instance: FlashcardDatabase? = null
fun getDatabase(context: Context): FlashcardDatabase {
return Instance ?: synchronized(this) {
Room.databaseBuilder(context, FlashcardDatabase::class.java, "flashcard_database")
.fallbackToDestructiveMigration()
.build()
.also { Instance = it }
}
}
}
}
Repository Interface
interface FlashCardsRepository {
fun getAllFlashcardsStream(): Flow<List<Flashcard>>
fun getFlashcardStream(id: Int): Flow<Flashcard?>
suspend fun insertFlashcard(flashcard: Flashcard)
suspend fun deleteFlashcard(flashcard: Flashcard)
suspend fun updateFlashcard(flashcard: Flashcard)
}
Repository implementation class
import kotlinx.coroutines.flow.Flow
class OfflineFlashcardsRepository(private val flashcardDao: FlashcardDao) : FlashCardsRepository {
override fun getAllFlashcardsStream(): Flow<List<Flashcard>> = flashcardDao.getAllFlashcards()
override fun getFlashcardStream(id: Int): Flow<Flashcard?> = flashcardDao.getFlashcard(id)
override suspend fun insertFlashcard(flashcard: Flashcard) = flashcardDao.insert(flashcard = flashcard)
override suspend fun updateFlashcard(flashcard: Flashcard) = flashcardDao.update(flashcard = flashcard)
override suspend fun deleteFlashcard(flashcard: Flashcard) = flashcardDao.delete(flashcard = flashcard)
}
App container (For dependency injections)
import android.content.Context
interface AppContainer {
val flashCardsRepository: FlashCardsRepository
}
class AppDataContainer(private val context: Context): AppContainer {
override val flashCardsRepository: FlashCardsRepository by lazy {
OfflineFlashcardsRepository(FlashcardDatabase.getDatabase(context).flashcardDao())
}
}
Flashcard Application to create an instance of the database onCreate() (I have already added this application to the manifest file)
import android.app.Application
import com.example.flashcardapp.data.AppContainer
import com.example.flashcardapp.data.AppDataContainer
class FlashcardApplication: Application() {
lateinit var container: AppContainer
override fun onCreate() {
super.onCreate()
container = AppDataContainer(this)
}
}
Manifest File
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:name=".FlashcardApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.FlashcardApp"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.FlashcardApp">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
答案1
得分: 1
你的问题可能是你实际上还没有访问数据库。
直到你尝试访问数据库之前,也就是插入/更新或读取数据之前。
仅仅创建/检索 Room 数据库的实例并不会创建数据库,实际的底层数据库的创建会被延迟到需要时(被访问时)。因此,你需要插入/更新或读取数据,然后数据库就会被创建。
英文:
Your issue could be that you haven't actually accessed the database.
That is until you attempt to access the database; i.e. insert/update or read data.
Simply creating/retrieving an instance of the Room Database does not create the database, the actual underlying database's creation is delayed until required (accessed). So you need to insert/update or read data and then the database will be created.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论