Попробуйте предварительно заполнить базу данных комнаты - PullRequest
0 голосов
/ 30 апреля 2020

Я пытаюсь создать базу данных, которая имеет две таблицы с отношением один ко многим. (один рецепт относится ко многим ингредиентам)

Кажется, я все настроил правильно, я думаю, но теперь, когда я создаю базу данных, я хочу предварительно заполнить ее некоторыми рецептами и ингредиентами, которые относятся к рецепту. Но я не знаю, как реализовать это в конструкторе баз данных.

Вот моя таблица рецептов:

@Entity(tableName = "recipe_table") //Represents the table in SQLite database
public class Recipe {

    @PrimaryKey(autoGenerate = true)
    private int id; //Holds the id of the recipe

    private String title; //Holds the name of the recipe

    @Ignore
    private List<Ingredient> ingredientsList;

    //Generate constructor to create objects later
    public Recipe(String title, List<Ingredient> ingredientsList) {
        this.title = title;
        this.ingredientsList = ingredientsList;
    }

    //Generate getters to persist values to the database
    public int getId() {
        return id;
    }

    //Generate setter so that room can recreate later
    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public List<Ingredient> getIngredientsList() {
        return ingredientsList;
    }

    public void setIngredientsList(List<Ingredient> ingredientsList) {
        this.ingredientsList = ingredientsList;
    }
}

Таблица ингредиентов:

package com.example.kookrecepten;

import androidx.room.Entity;
import androidx.room.ForeignKey;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;

import java.util.List;

import static androidx.room.ForeignKey.CASCADE;

@Entity(foreignKeys = @ForeignKey(entity = Recipe.class, parentColumns = "id", childColumns = "recipeId", onDelete = CASCADE))
public class Ingredient {
    @PrimaryKey
    private int id;
    private int recipeId;
    private String title; //Name of the ingredient
    @Ignore
    private List<Ingredient> ingredientsList;
    public Ingredient(String title, int recipeId) {
        this.title = title;
        this.recipeId = recipeId;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setRecipeId(int recipeId) {
        this.recipeId = recipeId;
    }

    public int getId() {
        return id;
    }

    public int getRecipeId() {
        return recipeId;
    }

    public String getTitle() {
        return title;
    }
}

Это мой файл дао

@Dao
public abstract class RecipeDao {
    //Insert recipe
    @Insert
    public abstract void insertRecipe(Recipe recipe);

    //Insert ingredients list
    @Insert
    public abstract void insertIngredientList(List<Ingredient> ingredients);

    @Query("SELECT * FROM recipe_table WHERE id =:id")
    public abstract Recipe getRecipe(int id);

    @Query("SELECT * FROM Ingredient WHERE recipeId =:recipeId")
    public abstract List<Ingredient> getIngredientList(int recipeId);

    public void insertRecipeWithIngredients(Recipe recipe) {
        List<Ingredient> ingredients = recipe.getIngredientsList();
        for (int i = 0; i < ingredients.size(); i++) {
            ingredients.get(i).setRecipeId(recipe.getId());
        }
        insertIngredientList(ingredients);
        insertRecipe(recipe);
    }

    public Recipe getRecipeWithIngredients(int id) {
        Recipe recipe = getRecipe(id);
        List<Ingredient> ingredients = getIngredientList(id);
        recipe.setIngredientsList(ingredients);
        return recipe;
    }
}

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

private static class PopulateDbAsyncTask extends AsyncTask<Void, Void, Void> {
        private RecipeDao recipeDao;

        private PopulateDbAsyncTask(RecipeDatabase db) {
            recipeDao = db.recipeDao();
        }

        @Override
        protected Void doInBackground(Void... voids) {
            recipeDao.insertRecipeWithIngredients(
                    //insert a recipe and a list of ingredients?
            );
            return null;
        }
    }

1 Ответ

0 голосов
/ 30 апреля 2020

Во-первых из всех, я рекомендую вам НЕ AsyncTask, поскольку он устарел . нажмите Официальная документация для получения более подробной информации.

Во-вторых вам 3 варианта предварительного заполнения базы данных:

1) createFromAssets : в этой опции вы можете создать каталог под названием «Базы данных» в папке ресурсов, чтобы вы могли выглядеть следующим образом:

.createFromAssets("/databases/YOUR DATABASE FILENAME")

2) createFromFile : эта опция может работать с файл, которому вы назначаете его путь.

.createFromFile(File("YOUR FILE PATH"))

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

    private fun copyDBFromStorage(databaseName: String) {
    if (checkIfDBExists(this, databaseName)) return
    val databaseFile = File(this.getDatabasePath(databaseName).toString())
    val sourceLocation = assets.open("Your database file path")
    try {
        val inputStream = sourceLocation
        val os = FileOutputStream(databaseFile)
        val buffer = ByteArray(1024 * 32)
        var length = inputStream.read(buffer)
        while (length > 0) {
            os.write(buffer, 0, length)
            length = inputStream.read(buffer)
        }
        os.flush()
        os.close()
        inputStream.close()

    } catch (ex: IOException) {
        ex.printStackTrace();
        throw  RuntimeException("Error copying storage database");
    }
}

private fun checkIfDBExists(
    context: Context,
    databaseName: String
): Boolean {
    val dbfile = File(context.getDatabasePath(databaseName).toString())
    if (dbfile.exists()) return true
    if (!dbfile.parentFile.exists()) {
        dbfile.parentFile.mkdirs()
    }
    return false
}

Надеюсь, это поможет

Счастливое кодирование ?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...