我在 Android Studio 中使用 Room 数据库,我似乎无法正确更新数据库中项目的字段

I'm using a Room database in Android Studio, and I can't seem to update correctly a field of an item in the database

我做 Android Studio 才一个月,我不得不说我对 Room 数据库有点困惑,如果这个问题听起来很困惑,我很抱歉。

我正在使用所述的 Room 数据库,这是我的数据库相关 类:

@Entity(tableName="board")
public class BoardItem {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name="board_id")
    private int boardId;
    @ColumnInfo(name="board_name")
    private String boardName;
    @ColumnInfo(name="board_description")
    private String boardDescription;
    @ColumnInfo(name="board_image_list")
    @TypeConverters(ImageListTypeConverter.class)
    private List<ImageItem> boardImageList;

    public BoardItem(String boardName, String boardDescription){
        this.boardName = boardName;
        this.boardDescription = boardDescription;
        this.boardImageList = new ArrayList<>();
    }

    public int getBoardId() { return boardId; }

    public String getBoardName() {
        return boardName;
    }

    public String getBoardDescription() {
        return boardDescription;
    }

    public String getPhotosCount() {
        return String.valueOf(this.boardImageList.size());
    }
    public void setBoardId(int boardId) {
        this.boardId = boardId;
    }

    public List<ImageItem> getBoardImageList() {
        return boardImageList;
    }

    public void setBoardImageList(List<ImageItem> list) { this.boardImageList = list; }
@Dao
public interface BoardItemDAO {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    void addBoardItem(BoardItem boardItem);

    @Transaction
    @Query("SELECT * from board ORDER BY board_id DESC")
    LiveData<List<BoardItem>> getBoardItems();

    @Transaction
    @Query("SELECT * from board ORDER BY board_id DESC")
    List<BoardItem> getBoardItemsNow();

}
@Database(entities =  {BoardItem.class}, version = 1)
public abstract class BoardItemDatabase  extends RoomDatabase {

    public abstract BoardItemDAO boardItemDAO();

    //Singleton
    private static volatile BoardItemDatabase INSTANCE;
    private static final int NUMBER_OF_THREADS = 4;
    static final ExecutorService databaseWriteExecutor = Executors.newFixedThreadPool(NUMBER_OF_THREADS);

    static BoardItemDatabase getDatabase(final Context context){

        if (INSTANCE == null) {
            synchronized (BoardItemDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(), BoardItemDatabase.class, "board_database")
                            .allowMainThreadQueries()
                            .build();
                }
            }
        }

        return INSTANCE;
    }

}
//Repository

public class BoardItemRepository {

    private BoardItemDAO boardItemDAO;
    private LiveData<List<BoardItem>> boardItemList;
    private List<BoardItem> boardItemListNow;

    public BoardItemRepository (Application application) {
        BoardItemDatabase db = BoardItemDatabase.getDatabase(application);
        boardItemDAO = db.boardItemDAO();
        boardItemList = boardItemDAO.getBoardItems();
        boardItemListNow = boardItemDAO.getBoardItemsNow();
    }

    //Room executes all queries on a separate thread
    //Observed LiveData will notify the observer when data has changed
    public LiveData<List<BoardItem>> getBoardItemList() { return boardItemList; }

    //this method is called on a non-UI thread or the app will throw an exception. Room ensures
    //that there are no long running operations on the main thread, blocking the UI.
    public void addBoardItem(final BoardItem boardItem) {
        BoardItemDatabase.databaseWriteExecutor.execute(() -> boardItemDAO.addBoardItem(boardItem));
    }

    public List<BoardItem> getBoardItemListNow() {return boardItemListNow; }

}

请注意,BoardItem 和 ImageItem 是 类 我自己创建的:一个板应该包含多个 ImageItem。

我的 boardItem 有不同的字段,其中之一是 ImageItems 列表。 现在,在一个特定的片段中,我尝试 更新这个 ImageItems 列表 在我的数据库中已经存在的板中,这是 id = 0 的板(数据库中的第一个板).我尝试从数据库中检索列表并将其替换为新列表。

我在某些情况下使用 LiveData 在项目更改时更新我的​​应用程序的视图,但是我的这段特定代码没有 LiveData 方法我需要在单击按钮后立即更改我的数据库包含此代码:

List<BoardItem> boardItems = boardListViewModel.getBoardItemsNow();

newList = boardItems.get(0).getBoardImageList();
newList.add(newItem);
boardItems.get(0).setBoardImageList(newList);

当我点击按钮时,代码执行没有错误,但数据库没有更新;它包含以前的列表,没有新项目。

提前致谢,如果这听起来令人困惑,我再次感到抱歉!

编辑: 这是我的视图模型:

public class BoardListViewModel extends AndroidViewModel {

    private final MutableLiveData<BoardItem> boardSelected = new MutableLiveData<>();
    private LiveData<List<BoardItem>> boardItems;
    private List<BoardItem> boardItemsNow;

    public BoardListViewModel(@NonNull Application application) {
        super(application);
        BoardItemRepository repo = new BoardItemRepository(application);
        boardItems = repo.getBoardItemList();
        boardItemsNow = repo.getBoardItemListNow();
    }

    public void select(BoardItem boardItem) {
        boardSelected.setValue(boardItem);
    }

    public LiveData<BoardItem> getSelected() {
        return boardSelected;
    }

    public LiveData<List<BoardItem>> getBoardItems() {
        return boardItems;
    }

    public BoardItem getBoardItem(int position) {
        return boardItems.getValue() == null ? null : boardItems.getValue().get(position);
    }

    public List<BoardItem> getBoardItemsNow() { return boardItemsNow; }
}

我认为您的问题是您没有更新而是试图通过 :-

添加(插入)新项目(行)
@Insert(onConflict = OnConflictStrategy.IGNORE)
void addBoardItem(BoardItem boardItem);

由于boardid已经存在,并且是主键,隐含唯一,所以发生冲突,忽略这个冲突,所以不添加新行,数据库保持不变。

你应该做的是更新现有的行,所以你需要一个 @Update dao。

所以添加然后使用以下 dao :-

@Update(onConflict = OnConflictStrategy.IGNORE)
int updateBoardItem(BoardItem boardItem);
  • 返回的 int 是已更新的行数(如果冲突导致更新被忽略,您会期望 1、0)。