Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
LeonDevLifeLog opened this issue Mar 11, 2019 · 20 comments
Open

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

LeonDevLifeLog opened this issue Mar 11, 2019 · 20 comments

Comments

@LeonDevLifeLog
Copy link

LeonDevLifeLog commented Mar 11, 2019

在模块化架构中,为了减少模块间的耦合,尽量想在每个模块中持有相关的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.

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

绝对模块化的好处

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

缺点

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

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

参考:

@anjiuzhe
Copy link

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

@jackchou
Copy link

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

@zcbiner
Copy link

zcbiner commented Nov 10, 2020

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

@censhengde
Copy link

censhengde commented Feb 24, 2021

好问题啊!!我也想知道

@nickalc
Copy link

nickalc commented Feb 24, 2022 via email

@hanyueziad
Copy link

hanyueziad commented Feb 24, 2022 via email

@272664150
Copy link

272664150 commented Feb 24, 2022 via email

@CodeIdeal
Copy link

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

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

@hanyueziad
Copy link

hanyueziad commented Mar 11, 2022 via email

@nickalc
Copy link

nickalc commented Mar 11, 2022 via email

@272664150
Copy link

272664150 commented Mar 11, 2022 via email

@duquewu
Copy link

duquewu commented Mar 11, 2022

不妨换个想法,在不同的子模块分别写 @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

@nicelyjust
Copy link

@geek5nan 没完全get

@nickalc
Copy link

nickalc commented Mar 17, 2023 via email

@hanyueziad
Copy link

hanyueziad commented Mar 17, 2023 via email

@272664150
Copy link

272664150 commented Mar 17, 2023 via email

@rotyan
Copy link

rotyan commented Mar 17, 2023 via email

@duquewu
Copy link

duquewu commented Mar 25, 2023

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

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

@Sheedon
Copy link

Sheedon commented Jul 31, 2023

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

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

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

@AceInAndroid
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

15 participants