【问题标题】:Room Persistence Library - CREATE VIEW房间持久性库 - 创建视图
【发布时间】:2018-12-17 19:12:16
【问题描述】:

我需要在使用 Room Persistence Library 的查询中使用 SQL VIEW。

使用 Commonsware 的回答 here 我已经能够在数据库创建期间运行原始 SQL 语句来创建视图。

 Room.databaseBuilder(context, MyDatabase.class, DB_NAME)
            .addCallback(new RoomDatabase.Callback() {
                @Override
                public void onCreate(@NonNull SupportSQLiteDatabase db) {
                    super.onCreate(db);
                    db.execSQL("CREATE VIEW view_name " +
                            "AS SELECT [...] "
                    );
                }
            })
            .build();

VIEW 实际上是在 SQLite DB 上创建的,并且工作正常,但我无法在我的 Dao 的 @Query 中引用它,因为我收到编译时错误:

Error:(100, 48) 错误:查询有问题:[SQLITE_ERROR] SQL 错误或缺少数据库(没有这样的表:view_name)

知道如何让 Room 知道我的观点或忽略错误吗?

【问题讨论】:

    标签: android-room


    【解决方案1】:

    2018 年 12 月 17 日更新

    Room 持久性库的 2.1.0 及更高版本现在提供对 SQLite 数据库视图的支持: https://developer.android.com/training/data-storage/room/creating-views (见 D-D 的评论)

    2017 年 15 月 12 日更新

    请注意,此解决方案实际上会破坏数据库迁移。

    问题在于视图中显然不存在的实体主键,因此迁移无效。

    请参阅CommonsWare's comment 了解可能的黑客解决方法。

    原始答案

    目前看来,使用 Room 是不可能的。

    无论如何,我已经使用解决方法完成了它:我创建了一个与视图具有相同名称和列的实体(实际上只有名称是必需的),这将在 DB 上创建一个表并允许您使用它没有编译时错误的查询中的表名。

    然后在 Room DB 创建期间,我在 CREATE VIEW 之前 DROP 这个实体的表。

    Room
        .databaseBuilder(context, DueDatabase.class, DB_NAME)
        .addCallback(new RoomDatabase.Callback() {
           @Override
           public void onCreate(@NonNull SupportSQLiteDatabase db) {
              super.onCreate(db);
              //Drop the fake table and create a view with the same name
              db.execSQL("DROP TABLE view_name");
              db.execSQL("CREATE VIEW view_name " +
                         "AS SELECT [...]"
              );
           }
        })
        .build();
    

    【讨论】:

    • 不错的解决方法!我没有看到已经为此提交的问题,所以I added one
    • @CommonsWare 请查看我对答案的更新,看来我的解决方案使迁移变得不可能。你有什么建议吗?
    • 是的,我对您遇到问题并不感到惊讶,尽管我希望您的解决方法可能会成立。关于我能想到的唯一一件事就是让您的迁移删除视图并创建一个合适的实体表,并在某处做一个注释,以触发您在迁移运行后恢复它(例如,在onOpen() 方法中RoomDatabase.Callback)。即使这可行,那也是您现有黑客方面的一个黑客,这开始变得可怕了。 :-(
    • 是的,我明白你的提议,我在放弃之前尝试过类似的事情。它变得非常 hacky,我更喜欢摆脱 DB 视图,直到 Room 得到适当的支持。一如既往地感谢CommonsGuy
    猜你喜欢
    • 2018-01-19
    • 1970-01-01
    • 2018-05-27
    • 2018-01-22
    • 1970-01-01
    • 2020-03-19
    • 2017-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多