Android 带有INSERT语句的RoomDatabase.query()未提交对数据库的更改
我正在RoomDatabase上执行SQL INSERT语句。 使用RoomDatabase.query进行相同的查询。但是,除非对返回的游标调用任何函数,否则插入的行不会提交到数据库-Android 带有INSERT语句的RoomDatabase.query()未提交对数据库的更改,android,android-room,android-architecture-components,Android,Android Room,Android Architecture Components,我正在RoomDatabase上执行SQL INSERT语句。 使用RoomDatabase.query进行相同的查询。但是,除非对返回的游标调用任何函数,否则插入的行不会提交到数据库- @Entity public class Person { @PrimaryKey @NonNull private String uuid; @Embedded @NonNull private Address address; public Per
@Entity
public class Person {
@PrimaryKey
@NonNull
private String uuid;
@Embedded
@NonNull
private Address address;
public Person(@NonNull String uuid, @NonNull Address address) {
this.uuid = uuid;
this.address = address;
}
@NonNull
public String getUuid() {
return uuid;
}
@NonNull
public Address getAddress() {
return address;
}
}
public class Address {
@NonNull
private String street;
@NonNull
private String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
@NonNull
public String getStreet() {
return street;
}
@NonNull
public String getCity() {
return city;
}
}
@Dao
public interface PersonDao {
@Query("SELECT * FROM Person")
List<Person> getPersons();
}
@TypeConverters(DateConverter.class)
@Database(entities = {Person.class}, version = 1, exportSchema = false)
public abstract class PersonDb extends RoomDatabase {
private static volatile PersonDb INSTANCE;
public abstract PersonDao getPersonDao();
public static PersonDb getInstance(Context context) {
if (INSTANCE == null) {
synchronized (PersonDb.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
PersonDb.class, "persons.db")
.allowMainThreadQueries()
.build();
}
}
}
return INSTANCE;
}
}
这是我的测试用例-
@RunWith(AndroidJUnit4.class)
public class PersonsIssueTest {
private final static String TAG = PersonsIssueTest.class.getSimpleName();
private PersonDb mDb;
private SimpleSQLiteQuery personsInsertQuery =
new SimpleSQLiteQuery("INSERT INTO Person (uuid, street, city) " +
"VALUES ('1', 'lane', 'york')");
@After
public void closeDb() throws IOException {
mDb.close();
}
@Test
public void insertQueryTest() {
Context context = InstrumentationRegistry.getTargetContext();
Cursor c;
mDb = PersonDb.getInstance(context);
PersonDao dao = mDb.getPersonDao();
List<Person> persons = dao.getPersons();
Log.d(TAG, "> number of persons " + persons.size() + " rows");
Log.d(TAG, "> running: " + personsInsertQuery.getSql());
c = mDb.query(personsInsertQuery);
/* If I comment the next statement, number of persons returned is 0 in the following dao.getPersons() */
c.moveToFirst();
c.close();
persons = dao.getPersons();
Log.d(TAG, "> number of persons " + persons.size() + " rows");
assertEquals(1, persons.size());
}
}
如果我首先注释c.moveToFirst,那么在下面的dao.getPersons中返回的人数是0
这里有什么问题吗?房间提供了一个内置的插入方法,您可以按如下方式进行设置
@Dao
public interface PersonDao {
@Query("SELECT * FROM Person")
List<Person> getPersons();
@Insert
void insertPersonData(Person person);
}
使用getOpenHelper.getWritableDatabase.execSQL,而不是查询。您看到的行为与SQLiteDatabase如何处理query和rawQuery是一致的,尽管这些方法不是为与INSERT一起使用而设计的;我使用查询来插入select from表,该表目前在房间中不受Dao支持。您能告诉我为什么需要对光标进行操作的帮助吗?我使用查询来插入select from表,该表目前在房间中不受Dao支持-我建议使用SupportSQLiteOpenHelper和支持SQLITE数据库。正如我在第一篇评论中提到的,您可以分别从getOpenHelper和getWritableDatabase获得这些。你能告诉我为什么需要对游标进行操作吗SQLITE数据库上的查询和rawQuery。SupportSQLiteDatabase实现也会以同样的方式工作。这很有帮助。谢谢。正如我在评论中已经提到的,我使用查询来插入select from表,到目前为止,房间中的Dao不支持该表。
dao.insertPersonData(personObject);