android-discuss icon indicating copy to clipboard operation
android-discuss copied to clipboard

[问答]Room数据库在模块化架构中的使用

Open LeonDevLifeLog opened this issue 6 years ago • 20 comments
trafficstars

在模块化架构中,为了减少模块间的耦合,尽量想在每个模块中持有相关的entity和DAO,但是ROOM数据库的架构需要注解所有的entity在一个抽象的AppDatabase类中,如果想减少耦合的话,需要在每一个业务module里声明一个AppDatabase单例,这样内存消耗就会过高,在官方文档中有这么一段备注:

Note: If your app runs in a single process, you should follow the singleton design pattern when instantiating an AppDatabase object. Each RoomDatabase instance is fairly expensive, and you rarely need access to multiple instances within a single process.

在另一篇文章中,也把相关的利弊说了一下

绝对模块化的好处

  • 迁移是模块化的
  • 查询会更快

缺点

  • 跨模块数据关系将不可能
  • 性能优化问题(自己补充的,如上官网备注)

想问问大家,有没有更好的方案

参考:

LeonDevLifeLog avatar Mar 11 '19 14:03 LeonDevLifeLog

同问,又想做到模块间的解耦,又想持有一个AppDatabase单例?难搞

anjiuzhe avatar Oct 26 '20 05:10 anjiuzhe

单独实现一个叫 database 都module,讲singleton实现在这个module里面,与database相关都data structure都单独定义,比如你要save user都资讯,dto叫做 userDto,为你的database module单独定义 DataUser,然后在要使用的module里面 implementation database这个module,这样可做到模块间的解耦也能做到全局的signleton

jackchou avatar Oct 26 '20 06:10 jackchou

我也碰到了这个问题。或许单独做一个database的module是一个相对较好的解决方案

zcbiner avatar Nov 10 '20 05:11 zcbiner

好问题啊!!我也想知道

censhengde avatar Feb 24 '21 12:02 censhengde

你好,邮件已收到,谢谢

nickalc avatar Feb 24 '22 03:02 nickalc

感谢您的关注,我会尽快给您答复

hanyueziad avatar Feb 24 '22 03:02 hanyueziad

这是来自QQ邮箱的假期自动回复邮件。   您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。

272664150 avatar Feb 24 '22 03:02 272664150

抽成单独的module是个解决办法. 我目前所在项目就是这么做的.

PS:楼上这些自动复回邮件的,能不能搞个白名单? 请尽量不要留下无意义复回@272664150 @hanyueziad @nickalc

CodeIdeal avatar Mar 11 '22 02:03 CodeIdeal

感谢您的关注,我会尽快给您答复

hanyueziad avatar Mar 11 '22 02:03 hanyueziad

你好,邮件已收到,谢谢

nickalc avatar Mar 11 '22 02:03 nickalc

这是来自QQ邮箱的假期自动回复邮件。   您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。

272664150 avatar Mar 11 '22 02:03 272664150

不妨换个想法,在不同的子模块分别写 @Entity、 @Dao 以及 @View,然后将这些子模块在 app 模块进行聚合,如下所示。

  • App
@Database(
  entities = [
    EntityA1::class,
    EntityA2::class,
    EntityB1::class,
    EntityB2::class
  ],
  views = [
  ],
  version = 1,
  autoMigrations = [

  ]
)
abstract class ConfigRepo : RoomDatabase(), IConfigRepo
  • Repo-API
interface IConfigRepo {
    fun entityA1Dao(): EntityA1Dao
    fun entityA2Dao(): EntityA2Dao
    fun entityB1Dao(): EntityB1Dao
    fun entityB2Dao(): EntityB2Dao
}
  • Repo-A
    • EntityA1
    • EntityA2
    • EntityA1Dao
    • EntityA2Dao
  • Repo-B
    • EntityB1
    • EntityB2
    • EntityB1Dao
    • EntityB2Dao

geek5nan avatar Mar 11 '22 05:03 geek5nan

@geek5nan 没完全get

nicelyjust avatar Mar 17 '23 09:03 nicelyjust

你好,邮件已收到,谢谢

nickalc avatar Mar 17 '23 09:03 nickalc

感谢您的关注,我会尽快给您答复

hanyueziad avatar Mar 17 '23 09:03 hanyueziad

这是来自QQ邮箱的假期自动回复邮件。   您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。

272664150 avatar Mar 17 '23 09:03 272664150

这是来自QQ邮箱的自动回复邮件。   您好,您的邮件已收到。如有后续我查收后会立刻联系您。如在假期,我将在假期结束后,尽快给您回复。

rotyan avatar Mar 17 '23 09:03 rotyan

@nicelyjust 题主担心多个模块各自实现一个 RoomDatabase可能会带来内存占用过高的问题。

我的建议是仅在 App 模块实现 RoomDatabase ,在这个单一的 RoomDatabase 上,组合各模块定义的 @Entity, @Dao,避免存在多个 RoomDatabase

geek5nan avatar Mar 25 '23 18:03 geek5nan

子模块中实现相应的Entity和Dao,在App中实现RoomDatabase,所有表的增删改,都在对应模块中实现,这是第一步。 这一步的问题就在于子模块改一遍,可能app模块中也要对应修改,比如增加一个User.class。

那么第二步,就是在编译时生成RoomDatabase,通过APT技术,扫描子模块中所对应内容(Entity、Dao、表更改语句等等)生成原本需要开发者实现的代码。 这应该就解决了「一个AppDatabase单例,又是解耦」。

以上是我的思路,有空我去写一个

Sheedon avatar Jul 31 '23 10:07 Sheedon

以上 思路不错 但关键还是路由支持依赖注入 这样子模块也可以获取到RoomDatabase的实例去拿Dao

AceInAndroid avatar Sep 22 '23 06:09 AceInAndroid