如何从Android Room中的多个数据库中进行选择(如何附加数据库)

Posted

技术标签:

【中文标题】如何从Android Room中的多个数据库中进行选择(如何附加数据库)【英文标题】:How to select from multiple databases in Android Room(How to attach databases) 【发布时间】:2018-10-05 12:54:40 【问题描述】:

如您所知,我们可以使用这样的附加命令从多个数据库中进行选择:

String path = DBHelper.getDatabasePath(context);
String sql = "ATTACH DATABASE '" + path + "/" + dbname.toString()
                + ".db' AS \"" + dbname.toString() + "\";";
db.execSQL(sql);

然后通过使用光标,我们可以从它们中进行选择。

通过使用 android Room,我该怎么做?是否有任何附件或类似命令可以执行此操作?

【问题讨论】:

【参考方案1】:

可以使用此代码附加另一个数据库

@Database(entities = Book.class, User.class, version = 1)
public abstract class LoanDatabase extends RoomDatabase 

    public abstract UserDao userDao();

    public abstract BookDao bookDao();

    private static LoanDatabase INSTANCE;

    public static LoanDatabase getInstance(Context context,final String attachDatabaseName) 
        if (INSTANCE == null) 
            INSTANCE = Room.databaseBuilder(context,
                    LoanDatabase.class, "LoanDatabase").addCallback(new Callback() 
                @Override
                public void onOpen(@NonNull SupportSQLiteDatabase db) 
                    attach(attachDatabaseName,"/data/data/com.test.roomwithdagger/databases/");
                    super.onOpen(db);
                
            )
                    .build();
        
        return INSTANCE;
    

    private static void attach(final String databaseName, final String databasePath) 
        String sql = "ATTACH DATABASE '" + databasePath + databaseName
                + "' AS \"" + databaseName + "\";";
        INSTANCE. mDatabase.execSQL(sql);
    


public void attachDatabase(String databaseName,String databasePath)

    String sql = "ATTACH DATABASE '" + databasePath + "/" + databaseName
            + ".db' AS \"" + databaseName + "\";";
    INSTANCE.mDatabase.execSQL(sql);


在 Dao 接口中使用@SkipQueryVerification 像这样跳过查询验证。

@Dao
public interface BookDao 

...

    @SkipQueryVerification
    @Query("SELECT * FROM main.Book b INNER JOIN LoanDatabase1.Loan l on b.Id=l.BookId where b.Id=:bookId")
    Book getBookAndLoan(int bookId);
...


使用:

LoanDatabase db = LoanDatabase.getInstance(this,"LoanDatabase1")

Book book= db.bookDao().getBookAndLoan(1)

【讨论】:

Dao中@Insert怎么样,插入多条记录,我们必须指定main或LoanDatabase1 DB,否则找不到表。 INSTANCE.mDatabase is deprecated in room.2.2.3 解决方案:SupportSQLiteDatabase sqLiteDatabase = INSTANCE.getOpenHelper().getWritableDatabase(); sqLiteDatabase.execSQL(sql); 如果我们像这样附加数据库,LiveData 不会为我触发。如果我评论附加,那么它就会被触发。需要帮助【参考方案2】:

在使用DatabaseBuilder 类构建房间数据库时,您可以选择注册一个callback,该callback 具有每次打开数据库时都会调用的方法:

 /**
         * Called when the database has been opened.
         *
         * @param db The database.
         */
        public void onOpen(@NonNull SupportSQLiteDatabase db) 
        

一种选择是使用db 参数注册此回调和ATTACH 您的其他数据库。然后在 dao 中,您可以进行引用另一个表的查询。

【讨论】:

以上是关于如何从Android Room中的多个数据库中进行选择(如何附加数据库)的主要内容,如果未能解决你的问题,请参考以下文章

使用 Android Room 从 Junction Table 获取数据

Android Room:使用 Room 插入关系实体

如何使用 Android Room 从数据库中获取一行? [复制]

Android Room LiveData观察器未更新

如何将 Not Null 表列迁移到 Android Room 数据库中的 Null

Android Room Database:如何嵌入多个实体