@RawQuery 与 ViewModel
@RawQuery with ViewModel
我遵循了这个Room With a View tutorial and everything works as expected. Now I'm trying to implement @RawQuery and display LiveData with ViewModel. I want to display a list of items that have a certain column value (in this case a String). In this documentation这段代码似乎是我想要的应用程序功能的解决方案:
@Dao
interface RawDao {
@RawQuery(observedEntities = User.class)
LiveData<List<User>> getUsers(SupportSQLiteQuery query);
}
LiveData<List<User>> liveUsers = rawDao.getUsers(
new SimpleSQLiteQuery("SELECT * FROM User ORDER BY name DESC"));
我希望在将 nameColumn 值传递到 simpleSQLiteQuery(String nameColumn)
函数 returns new SimpleSQLiteQuery
.
时在 运行 时构建我的读取查询
这是我的代码:
道
@Dao
public interface ShotDao {
@RawQuery(observedEntities = Shot.class)
LiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery);
}
存储库
private ShotDao mShotDao;
private LiveData<List<Shot>> mNameColumn;
private SimpleSQLiteQuery mSimpleSQLiteQuery;
public ShotRepository(Application application) {
WrappShotDatabase database = WrappShotDatabase.getDatabase(application);
mShotDao = database.shotDao();
mNameColumn = mShotDao.getNameColumn(mSimpleSQLiteQuery);
}
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
this.mSimpleSQLiteQuery = simpleSQLiteQuery;
return mNameColumn;
}
ViewModel
private ShotRepository mRepository;
private LiveData<List<Shot>> mNameColumn;
private SimpleSQLiteQuery mSimpleSQLiteQuery;
public ShotViewModel(Application application) {
super(application);
mRepository = new ShotRepository(application);
mNameColumn = mRepository.getNameColumn(mSimpleSQLiteQuery);
}
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
this.mSimpleSQLiteQuery = simpleSQLiteQuery;
return mNameColumn;
}
Activity
String columnName = mColumnName;
shotViewModel = ViewModelProviders.of(this).get(ShotViewModel.class);
shotViewModel.getNameColumn(simpleSQLiteQuery(columnName)).observe(this, new Observer<List<Shot>>() {
@Override
public void onChanged(@Nullable List<Shot> shots) {
mShotAdapter.submitList(shots);
}
});
简单的SQLiteQuery方法
private SimpleSQLiteQuery simpleSQLiteQuery(String nameColumn) {
String select = "SELECT * FROM ";
String tableName = "shots";
String where = " WHERE nameColumn=\"";
String close = "\"";
return new SimpleSQLiteQuery(select + tableName + where + nameColumn + close);
}
创建 Activity 时,我的应用程序崩溃并收到错误消息:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String android.arch.persistence.db.SupportSQLiteQuery.getSql()' on a null object reference
我不太明白为什么没有创建我的对象以及应该何时创建。 Logcat 还指出了 ShotDao_Impl.java 生成的源文件中的 A 行和 B 行。
@Override
public LiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery) {
final SupportSQLiteQuery _internalQuery = supportSQLiteQuery;
return new ComputableLiveData<List<Shot>>() { // row A
private Observer _observer;
@Override
protected List<Shot> compute() {
if (_observer == null) {
_observer = new Observer("shots") {
@Override
public void onInvalidated(@NonNull Set<String> tables) {
invalidate();
}
};
__db.getInvalidationTracker().addWeakObserver(_observer);
}
final Cursor _cursor = __db.query(_internalQuery); // row B
try {
final List<Shot> _result = new ArrayList<Shot>(_cursor.getCount());
while(_cursor.moveToNext()) {
final Shot _item;
_item = __entityCursorConverter_comExampleAndroidWrappDatabaseShot(_cursor);
_result.add(_item);
}
return _result;
} finally {
_cursor.close();
}
}
}.getLiveData();
}
viewmodel 中的这一行给你错误。您正在为空的房间数据库设置 mSimpleSQLiteQuery
。
mNameColumn = mRepository.getNameColumn(mSimpleSQLiteQuery);
您应该从视图模型中删除上面的行并修改 getNameColumn()
函数,如下所示:
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
return mRepository.getNameColumn(mSimpleSQLiteQuery);;
}
编辑:
您可以通过修改 DAO 来简化代码。您可以将参数直接传递给 DAO。
例如
@Query("SELECT * FROM shots WHERE nameColumn = :columnName")
LiveData<List<Shot>> getNameColumn(String columnName);
使用这个函数你可以根据列名
检索shots
ViewModel 中的 mNameColumn
LiveData 是在执行 ViewModel 构造函数时使用 null
mSimpleSQLiteQuery
创建的。您在 getNameColumn
中进行了设置,但请注意,您的实时数据不知道这个新值。
因此 ShotDao
对 LiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery);
的实现收到 null
SupportSQLiteQuery 导致崩溃。
我遵循了这个Room With a View tutorial and everything works as expected. Now I'm trying to implement @RawQuery and display LiveData with ViewModel. I want to display a list of items that have a certain column value (in this case a String). In this documentation这段代码似乎是我想要的应用程序功能的解决方案:
@Dao
interface RawDao {
@RawQuery(observedEntities = User.class)
LiveData<List<User>> getUsers(SupportSQLiteQuery query);
}
LiveData<List<User>> liveUsers = rawDao.getUsers(
new SimpleSQLiteQuery("SELECT * FROM User ORDER BY name DESC"));
我希望在将 nameColumn 值传递到 simpleSQLiteQuery(String nameColumn)
函数 returns new SimpleSQLiteQuery
.
这是我的代码:
道
@Dao
public interface ShotDao {
@RawQuery(observedEntities = Shot.class)
LiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery);
}
存储库
private ShotDao mShotDao;
private LiveData<List<Shot>> mNameColumn;
private SimpleSQLiteQuery mSimpleSQLiteQuery;
public ShotRepository(Application application) {
WrappShotDatabase database = WrappShotDatabase.getDatabase(application);
mShotDao = database.shotDao();
mNameColumn = mShotDao.getNameColumn(mSimpleSQLiteQuery);
}
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
this.mSimpleSQLiteQuery = simpleSQLiteQuery;
return mNameColumn;
}
ViewModel
private ShotRepository mRepository;
private LiveData<List<Shot>> mNameColumn;
private SimpleSQLiteQuery mSimpleSQLiteQuery;
public ShotViewModel(Application application) {
super(application);
mRepository = new ShotRepository(application);
mNameColumn = mRepository.getNameColumn(mSimpleSQLiteQuery);
}
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
this.mSimpleSQLiteQuery = simpleSQLiteQuery;
return mNameColumn;
}
Activity
String columnName = mColumnName;
shotViewModel = ViewModelProviders.of(this).get(ShotViewModel.class);
shotViewModel.getNameColumn(simpleSQLiteQuery(columnName)).observe(this, new Observer<List<Shot>>() {
@Override
public void onChanged(@Nullable List<Shot> shots) {
mShotAdapter.submitList(shots);
}
});
简单的SQLiteQuery方法
private SimpleSQLiteQuery simpleSQLiteQuery(String nameColumn) {
String select = "SELECT * FROM ";
String tableName = "shots";
String where = " WHERE nameColumn=\"";
String close = "\"";
return new SimpleSQLiteQuery(select + tableName + where + nameColumn + close);
}
创建 Activity 时,我的应用程序崩溃并收到错误消息:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String android.arch.persistence.db.SupportSQLiteQuery.getSql()' on a null object reference
我不太明白为什么没有创建我的对象以及应该何时创建。 Logcat 还指出了 ShotDao_Impl.java 生成的源文件中的 A 行和 B 行。
@Override
public LiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery) {
final SupportSQLiteQuery _internalQuery = supportSQLiteQuery;
return new ComputableLiveData<List<Shot>>() { // row A
private Observer _observer;
@Override
protected List<Shot> compute() {
if (_observer == null) {
_observer = new Observer("shots") {
@Override
public void onInvalidated(@NonNull Set<String> tables) {
invalidate();
}
};
__db.getInvalidationTracker().addWeakObserver(_observer);
}
final Cursor _cursor = __db.query(_internalQuery); // row B
try {
final List<Shot> _result = new ArrayList<Shot>(_cursor.getCount());
while(_cursor.moveToNext()) {
final Shot _item;
_item = __entityCursorConverter_comExampleAndroidWrappDatabaseShot(_cursor);
_result.add(_item);
}
return _result;
} finally {
_cursor.close();
}
}
}.getLiveData();
}
viewmodel 中的这一行给你错误。您正在为空的房间数据库设置 mSimpleSQLiteQuery
。
mNameColumn = mRepository.getNameColumn(mSimpleSQLiteQuery);
您应该从视图模型中删除上面的行并修改 getNameColumn()
函数,如下所示:
public LiveData<List<Shot>> getNameColumn (SimpleSQLiteQuery simpleSQLiteQuery) {
return mRepository.getNameColumn(mSimpleSQLiteQuery);;
}
编辑:
您可以通过修改 DAO 来简化代码。您可以将参数直接传递给 DAO。
例如
@Query("SELECT * FROM shots WHERE nameColumn = :columnName")
LiveData<List<Shot>> getNameColumn(String columnName);
使用这个函数你可以根据列名
检索shots
ViewModel 中的 mNameColumn
LiveData 是在执行 ViewModel 构造函数时使用 null
mSimpleSQLiteQuery
创建的。您在 getNameColumn
中进行了设置,但请注意,您的实时数据不知道这个新值。
因此 ShotDao
对 LiveData<List<Shot>> getNameColumn(SupportSQLiteQuery supportSQLiteQuery);
的实现收到 null
SupportSQLiteQuery 导致崩溃。