【问题标题】:How to select from multiple databases in Android Room(How to attach databases)如何从Android Room中的多个数据库中进行选择(如何附加数据库)
【发布时间】: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,我该怎么做?是否有任何附件或类似命令可以执行此操作?

【问题讨论】:

    标签: java android sqlite android-room android-architecture-components


    【解决方案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 中,您可以进行引用另一个表的查询。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多