我在 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)。
我做 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)。