6

我是 Room、Rxjava 和其他 android 架构组件的新手。我正在尝试更新/插入 2 条记录(如果行已经存在,请更新它。否则插入一个新行。)我尝试按以下方式进行操作。但是,我没有工作。

游戏活动:

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();
            }));        
      }
}

游戏视图模型:

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);
      }
   }
}

本地用户数据源

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);
    }
}

道访问

@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 损失列)。如果用户在表中不存在,则创建一个新条目。

4

2 回答 2

4

您的用户 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;
 }
于 2018-04-14T10:04:13.193 回答
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
于 2020-10-01T01:46:19.513 回答