我是Room,Rxjava和其他Android架构组件的新手。我正在尝试更新/插入2条记录(如果行已经存在,请更新它。否则插入一个新行。)我试图按照以下方式进行操作。但是,我没有工作。
GameActivity:
public class GameActivity extends AppCompatActivity {
...
public void onGameWinnerChanged(Player winner) {
mDisposable.add(gameViewModel.updateDb(winner)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> Log.e("Success!!!", "updated records")
, throwable -> {
throwable.printStackTrace();
}));
}
}
GameViewModel:
public class GameViewModel extends ViewModel {
...
public Completable updateDb(Player winner) {
return Completable.fromAction(() -> {
updateWinner(winner);
Player loser = game.player1 == winner ? game.player2 : game.player1;
updateLoser(loser);
});
}
private void updateLoser(Player loser) {
User user = userDataSource.getSingleRecordFromName(loser.name);
if (user != null) {
user.loss++;
userDataSource.updateRecord(user);
} else {
user = new User(loser.name, "", 0, 0, 1);
userDataSource.insertOrUpdateUser(user);
}
}
private void updateWinner(Player winner) {
User user = userDataSource.getSingleRecordFromName(winner.name);
if (user != null) {
user.wins++;
userDataSource.updateRecord(user);
} else {
user = new User(winner.name, "", 0, 1, 0);
userDataSource.insertOrUpdateUser(user);
}
}
}
LocalUserDataSource
public class LocalUserDataSource implements UserDataSource {
private DaoAccess daoAccess;
public LocalUserDataSource(DaoAccess daoAccess){
this.daoAccess=daoAccess;
}
@Override
public Flowable<List<User>> getUsers() {
return daoAccess.fetchAllData();
}
@Override
public void insertOrUpdateUser(User user) {
Log.e("local user ds","insertOrUpdateUser");
daoAccess.insertOnlySingleRecord(user);
}
@Override
public User getSingleRecordFromName(String strName) {
return daoAccess.getSingleRecord(strName);
}
@Override
public void updateRecord(User user) {
daoAccess.updateRecord(user);
}
@Override
public void deleteRecord(User user) {
daoAccess.deleteRecord(user);
}
}
DaoAccess
@Dao
public interface DaoAccess {
@Insert
void insertOnlySingleRecord(User user);
@Query("SELECT * FROM User")
Flowable<List<User>> fetchAllData();
@Query("SELECT * FROM User WHERE name =:strName")
User getSingleRecord(String strName);
@Update
void updateRecord(User user);
@Delete
void deleteRecord(User user);
}
问题是,当我尝试运行时,如果我尝试在GameViewModel类的以下行中插入任何不在数据库中的用户,则会出现NullPointer异常。
User user = userDataSource.getSingleRecordFromName(loser.name);
谁能告诉我哪里错了或我该怎么办?
修改
我想要做的是首先获取一个用户,如果它在数据库中,更新增量或减少分数(如果胜者然后+1胜利列,如果失败者然后+1损失列)。 如果表中不存在用户,则创建一个新条目。
答案 0 :(得分:2)
您的用户Dao 应如下所示
@Dao
public interface DaoAccess {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insertOnlySingleRecord(User user);
@Query("SELECT * FROM User")
Flowable<List<User>> fetchAllData();
@Query("SELECT * FROM User WHERE lower(name) = lower(:strName) limit 1")
User getSingleRecord(String strName);
@Update
void updateRecord(User user);
@Delete
void deleteRecord(User user);
}
您的用户实体应该像
@Entity(tableName = "user_table", indices = @Index(value = {"name"}, unique = true))
public class UserEntity {
@PrimaryKey(autoGenerate = true)
private int id;
@ColumnInfo(name = "name")
private String name;
}
答案 1 :(得分:0)
使用此查询,您可以简单地检查数据库中是否存在数据
// It will return **TRUE** if user exist in User Table else return **FALSE**
@Query("SELECT * FROM User WHERE name == :strName")
fun isUserExist(strName: String): Boolean
// It will return **user count** if user exist in User Table else return **0**
@Query("SELECT * FROM User WHERE name == :strName")
fun isUserExist(strName: String): Int
// It will return **User** if user exist in User Table else return **null**
@Query("SELECT * FROM User WHERE name == :strName")
fun isUserExist(strName: String): User