如果 Sqlite 和 Room 都存在于同一个项目中,并且在 Android 中具有相同的数据库名称,会不会有任何冲突?

Aja*_*J G 6 database sqlite android android-room

我有几个旧模块使用SQlite Db,新模块使用Room DB(都在同一个项目中,SQlite尚未迁移到Room),都使用相同的数据库名称,会不会有冲突?

例如:数据库名称是“user_table”与 SQLite 我有 2 个表和新的要求使用相同数据库名称下的新表的空间。它会对已经创建的数据库造成任何问题吗?如果是,我将如何解决这个问题?

Mik*_*keT 1

如果您打算使用 Room 中的原始表,那么您可能会遇到一些问题,因为 Room 对于与相应实体匹配的表非常具体,例如只能使用列类型 TEXT、INTEGER、REAL 和 BLOB,不能隐含 null,因此必须例如用于 java 原语(使用 Long 而不是 long 等可以解决此类问题,Room 的更高版本扩展了此要求,即表与默认值匹配实体(我相信))。

如果您只是在房间一侧使用新表,那么非房间和房间可以共存。那么问题就变成了多个连接的使用。如果您可以使用SupportSQLiteDatabase而不是SQLiteDatabase,然后仅使用单个连接(请注意,与 SQLiteDatabase 相比,SupportSQLiteDatabase 受到限制),您也许能够绕过此问题。

  • 例如,SQLiteDatabase查询方法通过 7 个或更多参数构建 SQL,而SupportSQliteDatabase的查询将 SQL 作为单个参数。

简单的例子

以下是一个简单的应用程序,可以在仅使用预房间表 (mytable) 和通过 SupportSQliteDatabase 结合使用附加房间表 (roomtable) 和 mytable 之间进行切换。

首先是扩展 SQLiteOPenHelper(又名 pre-room)的 DatabaseHelper,即DatabaseHelperPreRoom.java

public class DatabaseHelperPreRoom extends SQLiteOpenHelper {
    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;
    public static final String TABLE_MYTABLE = "mytable";
    public static final String COL_MYTABLE_ID = BaseColumns._ID;
    public static final String COl_MYTABLE_NAME = "name";

    SQLiteDatabase mDB;

    public DatabaseHelperPreRoom(Context context) {
        super(context,DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_MYTABLE +
                "(" +
                COL_MYTABLE_ID + " INTEGER PRIMARY KEY," +
                COl_MYTABLE_NAME + " TEXT UNIQUE " +
                ")");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public long insert(String name) {
        ContentValues cv = new ContentValues();
        cv.put(COl_MYTABLE_NAME,name);
        return mDB.insert(TABLE_MYTABLE,null,cv);
    }

    public Cursor getAll() {
        return mDB.query(TABLE_MYTABLE,null,null,null,null,null,null);
    }

    public static long insertPostRoom(SupportSQLiteDatabase db, String name) {
        ContentValues cv = new ContentValues();
        cv.put(COl_MYTABLE_NAME,name);
        return db.insert(TABLE_MYTABLE, OnConflictStrategy.IGNORE,cv);
    }

    public static Cursor getAllPostRoom(SupportSQLiteDatabase db) {
        return db.query("SELECT * FROM " + TABLE_MYTABLE);
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 请注意最后添加的两个静态方法,以准备将 Room 添加到混合中。

roomtable 表的 Room 实体(与 mytable 基本相同)RoomTable.java :-

@Entity(tableName = "roomtable")
public class RoomTable {

    @PrimaryKey
    @ColumnInfo(name = BaseColumns._ID)
    Long id;
    String name;

    public RoomTable () {}

    @Ignore
    public RoomTable(String name) {
        this.id = null;
        this.name = name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

Dao RoomTableDao.java

@Dao
public interface RoomTableDao {

    @Insert
    long insert(RoomTable roomTable);

    @Query("SELECT * FROM roomtable")
    List<RoomTable> getAll();

    @Query("SELECT count() AS " + BaseColumns._COUNT + " FROM roomtable")
    long getRowCount();
}
Run Code Online (Sandbox Code Playgroud)

房间数据库RoomTableDatabase.java

@Database(version = DatabaseHelperPreRoom.DBVERSION, entities = {RoomTable.class})
public abstract class RoomTableDatabase extends RoomDatabase {

    abstract RoomTableDao roomTableDao();
}
Run Code Online (Sandbox Code Playgroud)

最后将所有内容放在一个 Activity 中,使用允许在 pre-room 和 room + pre-room MainActivity.java之间进行简单切换的代码

public class MainActivity extends AppCompatActivity {

    public static final Boolean USINGROOM = true; //<<<<<<<<<< Switch control
    DatabaseHelperPreRoom mDBHlpr;
    RoomTableDatabase mRoomDB;
    RoomTableDao roomTableDao;
    SupportSQLiteDatabase mSDB;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //<<<<<<<<<< The SWITCH as to use Pre-Room or ROOM
        if (!USINGROOM) {
            PreRoomCode();
        } else {
            PostRoomCode();
        }
    }

    private void PreRoomCode() {
        // Adds 3 rows if none exist and then log the data.
        mDBHlpr = new DatabaseHelperPreRoom(this);
        if (DatabaseUtils.queryNumEntries(mDBHlpr.getWritableDatabase(),DatabaseHelperPreRoom.TABLE_MYTABLE) < 1) {
            mDBHlpr.insert("A");
            mDBHlpr.insert("B");
            mDBHlpr.insert("C");
        }
        Cursor csr = mDBHlpr.getAll();
        while (csr.moveToNext()) {
            Log.d(
                    "PREROOMINFO",
                    "Name is " + csr.getString(csr.getColumnIndex(DatabaseHelperPreRoom.COl_MYTABLE_NAME)) +
                            " ID is " + csr.getString(csr.getColumnIndex(DatabaseHelperPreRoom.COL_MYTABLE_ID))
            );
        }
        csr.close();
    }


    private void PostRoomCode() {
        // Get around the fact that Room will only create it's tables for a new database
        createRoomTableIfNeeded();
        // Build the Room database
        mRoomDB = Room.databaseBuilder(this,RoomTableDatabase.class,DatabaseHelperPreRoom.DBNAME)
                .allowMainThreadQueries()
                .build();
        roomTableDao = mRoomDB.roomTableDao();
        // Get a SupportSQliteDatabase for use later
        mSDB = mRoomDB.getOpenHelper().getWritableDatabase();

        // If no rows then add 3 to new room table and another 3 to the pre-room table
        // i.e. basic proof of concept
        if (roomTableDao.getRowCount() < 1) {
            roomTableDao.insert(new RoomTable("X"));
            roomTableDao.insert(new RoomTable("Y"));
            roomTableDao.insert(new RoomTable("Z"));

            DatabaseHelperPreRoom.insertPostRoom(mSDB,"M");
            DatabaseHelperPreRoom.insertPostRoom(mSDB,"N");
            DatabaseHelperPreRoom.insertPostRoom(mSDB,"O");
        }
        // Show whats in the room table
        List<RoomTable> roomTableList = roomTableDao.getAll();
        for (RoomTable r: roomTableList) {
            Log.d("ROOMINFO","Name is " + r.getName() + " ID is " + r.getId());
        }
        // Show whats in the pre-room table
        Cursor csr = DatabaseHelperPreRoom.getAllPostRoom(mSDB);
        while (csr.moveToNext()) {
            Log.d(
                    "PREROOMINFO",
                    "Name is " + csr.getString(csr.getColumnIndex(DatabaseHelperPreRoom.COl_MYTABLE_NAME)) +
                            " ID is " + csr.getString(csr.getColumnIndex(DatabaseHelperPreRoom.COL_MYTABLE_ID))
            );
        }
    }


    private void createRoomTableIfNeeded() {
        /* As the Room table will not exist and will not get created as the db exists
            this is used to create the table.
         */
        SQLiteDatabase db = SQLiteDatabase.openDatabase(this.getDatabasePath(DatabaseHelperPreRoom.DBNAME).getPath(),null,SQLiteDatabase.OPEN_READWRITE);
        Cursor csr = db.query("sqlite_master",null,"name=?  AND type=?",new String[]{"roomtable","table"},null,null,null);
        int rowcount = csr.getCount();
        csr.close();
        if (rowcount == 0) {
            // CREATE SQL COPIED FROM RoomTableDatabase_Impl in java generated so the expected table is created
            db.execSQL("CREATE TABLE IF NOT EXISTS `roomtable` (`_id` INTEGER, `name` TEXT, PRIMARY KEY(`_id`))");
        }
        db.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

结果

使用房间=假;

2019-11-06 20:50:09.665 D/PREROOMINFO: Name is A ID is 1
2019-11-06 20:50:09.665 D/PREROOMINFO: Name is B ID is 2
2019-11-06 20:50:09.665 D/PREROOMINFO: Name is C ID is 3
Run Code Online (Sandbox Code Playgroud)
  • 无论房间表是否存在,结果都是相同的,因此随时切换到 false 会产生相同的结果。

使用房间=真;

2019-11-06 20:52:44.042 D/ROOMINFO: Name is X ID is 1
2019-11-06 20:52:44.042 D/ROOMINFO: Name is Y ID is 2
2019-11-06 20:52:44.042 D/ROOMINFO: Name is Z ID is 3
2019-11-06 20:52:44.043 D/PREROOMINFO: Name is A ID is 1
2019-11-06 20:52:44.043 D/PREROOMINFO: Name is B ID is 2
2019-11-06 20:52:44.043 D/PREROOMINFO: Name is C ID is 3
2019-11-06 20:52:44.043 D/PREROOMINFO: Name is M ID is 4
2019-11-06 20:52:44.043 D/PREROOMINFO: Name is N ID is 5
2019-11-06 20:52:44.043 D/PREROOMINFO: Name is O ID is 6
Run Code Online (Sandbox Code Playgroud)
  • 同样,您可以在“房间”和“房间前”模式之间切换,除了结果之外不会产生任何影响。