我只做了一个月的Android Studio,我不得不说我对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是我自己创建的类:一个board应该包含多个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);
当我点击按钮时,代码执行没有错误,但数据库没有更新;它包含之前的列表,没有新项。
提前感谢,再次抱歉,如果这听起来令人困惑!
编辑:这是我的ViewModel:
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)。