Android同一Room数据库是否支持创建多个DAO文件?
同一个Android Room数据库定义多个DAO是完全支持的,你的报错由代码写法错误导致,按以下步骤修复即可:
核心错误原因
- 你在
createDatabase方法中构建数据库实例后链式调用DAO方法属于错误写法:调用build()得到的是CArchDatabase实例,调用dao1()后返回值就变成了Dao1的实例,Dao1类中不存在dao2()方法,要么直接编译报错,要么运行时报方法不存在的崩溃。同时你的createDatabase方法声明返回值是父类RoomDatabase,后续拿DAO时需要强转,本身也有类型安全问题。 - Koin依赖配置中只声明了数据库实例的注入,没有声明各个DAO的注入规则,你在依赖
ContaBancariaDao时直接用get()拿不到对应实例,会触发Koin的注入异常。
修复步骤
1. 修正数据库类代码
删除createDatabase里的DAO链式调用,同时修正返回值类型为CArchDatabase:
@Database(version = 1, entities = [ContaBancaria::class, Entity1::class, Entity2::class, Entity3::class /* 其余实体依次添加 */]) abstract class CArchDatabase : RoomDatabase() { abstract fun contaBancariaDao(): ContaBancariaDao abstract fun dao1(): Dao1 abstract fun dao2(): Dao2 abstract fun dao3(): Dao3 // 其余DAO抽象方法依次声明 companion object { fun createDatabase(context: Context): CArchDatabase { return Room.databaseBuilder(context, CArchDatabase::class.java, "CArchDatabase.db") .fallbackToDestructiveMigration() .build() } } }
注:实体类、DAO类名首字母请按Kotlin规范大写,避免语法问题
2. 修正Koin依赖注入配置
新增各个DAO的注入声明,所有DAO都从单例的数据库实例中获取:
val cacheDataModule = module { // 数据库单例 single { CArchDatabase.createDatabase(androidContext()) } // 各个DAO的注入声明 single { get<CArchDatabase>().contaBancariaDao() } single { get<CArchDatabase>().dao1() } single { get<CArchDatabase>().dao2() } single { get<CArchDatabase>().dao3() } // 其余DAO依次添加 factory<ContaBancariaCacheDataSource> { ContaBancariaCacheDataSourceImpl( contaBancariaDao = get() ) } // 其他需要依赖DAO的实例同理配置 }
注意事项
- 所有在
entities数组中声明的类必须添加@Entity注解,否则会触发Room编译错误 - 调试阶段可以用
fallbackToDestructiveMigration()跳过迁移逻辑,正式上线前需要替换为合法的Migration实现,避免用户升级应用时丢失本地数据 - 多个DAO可以操作同一个表,也可以操作不同表,Room本身没有限制,按业务需求划分即可
内容的提问来源于stack exchange,提问作者Romeu Carvalho Antunes
相关产品推荐
相关产品推荐

