Заполните базу данных комнат с Arraylist - PullRequest
0 голосов
/ 27 ноября 2018

Я хотел бы создать Deckbuilder, который позволит вам сохранять созданные колоды локально на устройстве.

Список Decklist хранится в Arraylists, который называется TransferDeck.Который я хотел бы хранить в комнате базы данных. Моя проблема в том, что я не знаю, как правильно заполнить свою базу данных данными, поступающими из Arraylist.

Я привык работать с Arraylist, и ниже вы видите мою попыткудля хранения данных:

Так вот, что я пытался, но, к сожалению, не работает:

private void populateDB(final List<TransferDeck> mTransferDeck) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    List<SaveDeck> mSaveDeck = new ArrayList<>();
                    for(int i = 0; i<mTransferDeck.size(); i++){
                        mSaveDeck.add(new SaveDeck(i, "FirstSavedDeck", mTransferDeck.get(i).getCardImage() ,mTransferDeck.get(i).getTypeImage(), mTransferDeck.get(i).getCost(), mTransferDeck.get(i).getName(), mTransferDeck.get(i).getNumber()));
                    }
                    mSavedDecksDB.deckBuilderDao().insertCards(mSaveDeck);

                }
            }).start();
}

Ниже вы можете найтиостальная часть моего кода, но приведенного выше должно быть достаточно, чтобы прояснить, что я хочу сделать ...

  1. Я создал класс SaveDeck, который должен быть в состоянии Сохранить колоду с заданным именем колоды :: -

    @ Открытый класс сущности SaveDeck реализует Serializable {@PrimaryKey (autoGenerate = true) private int _id;

    public SaveDeck(int _id, String deckName, int cardImage, int typeImage, Integer cardCost, String cardName, Integer cardNumber) {
        this._id = _id;
        DeckName = deckName;
        CardImage = cardImage;
        TypeImage = typeImage;
        CardCost = cardCost;
        CardName = cardName;
        CardNumber = cardNumber;
    }
    
    @ColumnInfo(name = "DeckName")
    private String DeckName;
    
    @ColumnInfo(name = "CardImage")
    private int CardImage;
    
    @ColumnInfo(name = "TypeImage")
    private int TypeImage;
    
    @ColumnInfo(name = "CardCost")
    private Integer CardCost;
    
    @ColumnInfo(name = "CardName")
    private String CardName;
    
    @ColumnInfo(name = "CardNumber")
    private Integer CardNumber;
    

    }

  2. Я создал класс Dao следующим образом: -

    @ Открытый интерфейс Dao DeckBuilderDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    public long[] insertCards(SaveDeck... saveDecks);
    
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    public long insertCard(SaveDeck saveDecks);
    
    @Update
    public int updateCardBaseEntries(SaveDeck... saveDecks);
    
    @Update
    public int updateCardBaseEntry(SaveDeck saveDecks);
    
    @Delete
    public int deleteCardBaseEntried(SaveDeck... saveDecks);
    
    @Delete
    public int deleteCardBaseEntry(SaveDeck saveDecks);
    
    @Query("SELECT * FROM SaveDeck")
    public SaveDeck[] getAllDecks();
    
    //probably I do not need the getAllDecks Query. Right now I only need the following one:
    @Query("SELECT * FROM SaveDeck WHERE DeckName = :NameOfDeck ORDER  BY DeckName, CardName")
    public SaveDeck getOneDeck(String NameOfDeck);
    

    }

  3. Кроме того, создан класс базы данных:

    @Database(entities = {SaveDeck.class}, version = 1)
    public abstract class SaveDecksDataBase extends RoomDatabase {
        public abstract DeckBuilderDao deckBuilderDao();
    }
    
  4. Последний класс является фрагментом, где я пытаюсь заполнитьсъел мою базу данных, и в populateDB() классе есть проблема

    открытый класс review_fragment extends Fragment {

    private List<TransferDeck> mTransferDeck = DataHolder.getInstance().savedDecklistTransfer;
    SaveDecksDataBase mSavedDecksDB;
    Cursor mCursor;
    
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    //return super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.review_fragment, container, false);
    
        /*Introduce Cards Recycler*/
    
        RecyclerView rvCards = view.findViewById(R.id.rv_review_cardlist);
        rvCards.setLayoutManager(new GridLayoutManager(getActivity(), 5));
        review_RViewAdapter_Cards adapterCards = new review_RViewAdapter_Cards(getContext(), mTransferDeck);
        rvCards.setAdapter(adapterCards);
    
    
    
        /*Init Room database*/
        mSavedDecksDB = Room.databaseBuilder(getActivity(),SaveDecksDataBase.class,"SavedDecksDB.db").build();
        populateDB(mTransferDeck);
    
        return view;
    }
    
    private void populateDB(final List<TransferDeck> mTransferDeck) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<SaveDeck> mSaveDeck = new ArrayList<>();
                for(int i = 0; i<mTransferDeck.size(); i++){
                    mSaveDeck.add(new SaveDeck(i, "FirstSavedDeck", mTransferDeck.get(i).getCardImage() ,mTransferDeck.get(i).getTypeImage(), mTransferDeck.get(i).getCost(), mTransferDeck.get(i).getName(), mTransferDeck.get(i).getNumber()));
                }
                mSavedDecksDB.deckBuilderDao().insertCards(mSaveDeck);
    
            }
        }).start();
    }
    

    }

1 Ответ

0 голосов
/ 27 ноября 2018

Я хотел бы упомянуть, что это должен быть комментарий, а не ответ.

Во-первых, либо используйте AysncTask, либо используйте более надежный Executors.newSingleThreadExecutor().Если вы предпочитаете второй вариант, то лучше создать вспомогательный класс (пример) .Пример:

private void populateDB(final List<TransferDeck> mTransferDeck) {
    AppExecutors.diskIO().execute(() -> {

        for(int i = 0; i<mTransferDeck.size(); i++){
            mSavedDecksDB.deckBuilderDao().insertCards(new SaveDeck(...);
        }

    });
}

(1) Создайте пустой конструктор.

(4) База данных комнаты не должна инициализироваться там, и лучше, если она одиночная.Таким образом, класс вашей базы данных (3) может выглядеть следующим образом:

public abstract class SaveDecksDataBase extends RoomDatabase {

   private static SaveDecksDataBase sINSTANCE;
   private static final Object LOCK = new Object();

   public static SaveDecksDataBase getDatabase(final Context context) {
        if (sINSTANCE == null) {
            synchronized (LOCK) {
                if (sINSTANCE == null) {
                    sINSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            SaveDecksDataBase.class, "SavedDecksDB.db")
                            .build();
                }
            }
        }
        return sINSTANCE;
    }

    public abstract DeckBuilderDao deckBuilderDao();
}

Наконец, чтобы получить SaveDeck объект, вы также должны использовать Executors или AsyncTask для выполнения работы в фоновом режиме, а затемзаполните RecyclerView.

  1. База данных комнат Android
  2. Практический набор
...