【问题标题】:What to Store from my model objects in Room Database从房间数据库中的模型对象中存储什么
【发布时间】:2018-01-20 14:04:01
【问题描述】:

我有 3 个 POJO 课程。 RecipeIngredientStep

我希望能够在离线时浏览我的食谱,所以我决定使用Room

Recipe.class

@Entity(tableName = "recipe")
public class Recipe implements Parcelable {

   @PrimaryKey(autoGenerate = false)
   @SerializedName("id")
   public int recipeId;

   @ColumnInfo(name = "recipe_name")
   public String name;

   @TypeConverters(Converters.class)
   public List<Ingredient> ingredients = null;

   @TypeConverters(Converters.class)
   public List<Step> steps = null;

   @ColumnInfo(name = "recipe_servings")
   public int servings;

   @Ignore
   public String image;

  public Recipe(int recipeId, String name, List<Ingredient> ingredients, List<Step> steps, int servings, String image) {
    this.recipeId = recipeId;
    this.name = name;
    this.ingredients = ingredients;
    this.steps = steps;
    this.servings = servings;
    this.image = image;
}
...
//getters and setters
...

Converters.class

public class Converters {

    static Gson gson = new Gson();

    @TypeConverter
    public static List<Ingredient> stringToIngredientList(String data) {
        if (data == null) {
            return Collections.emptyList();
        }

        Type listType = new TypeToken<List<Ingredient>>() {}.getType();

        return gson.fromJson(data, listType);
    }

    @TypeConverter
    public static String ingredientListToString(List<Ingredient> ingredients) {
        return gson.toJson(ingredients);
    }

    @TypeConverter
    public static List<Step> stringToStepList(String data) {
        if (data == null) {
            return Collections.emptyList();
        }

        Type listType = new TypeToken<List<Step>>() {}.getType();

        return gson.fromJson(data, listType);
    }

    @TypeConverter
    public static String stepListToString(List<Step> steps) {
        return gson.toJson(steps);
    }
}

RecipeDatabase.class

@Database(entities = {Recipe.class}, version = 1)
abstract class RecipeDatabase extends RoomDatabase {

    private static RecipeDatabase INSTANCE;

    public abstract RecipeDao recipeDao();

    public static RecipeDatabase getRecipeDatabase(Context context) {
        if (INSTANCE == null) {
            INSTANCE =
                    Room.databaseBuilder(context.getApplicationContext(), RecipeDatabase.class, "recipe-database")
                        // allow queries on the main thread.
                        // Don't do this on a real app! See PersistenceBasicSample for an example.
                        .allowMainThreadQueries()
                        .build();
        }
        return INSTANCE;
    }

    public static void destroyInstance() {
        INSTANCE = null;
    }
 }

RecipeDao.class

@Dao
public interface RecipeDao {

    @Query("SELECT * FROM recipe")
    List<Recipe> getAll();

    @Query("SELECT * FROM recipe where recipe_name LIKE  :name")
    Recipe findByName(String name);

    @Query("SELECT COUNT(*) from recipe")
    int countRecipes();

    @Update
    void update(Recipe... recipes);

    @Insert
    void insertAll(Recipe... recipes);

    @Delete
    void delete(Recipe recipe);
}

我的问题:在使用 Converters 类将 List&lt;Step&gt;List&lt;Ingredient&gt; 保存为 Strings 之后,我是否还应该保存我的每个 Step.class 的数据库>Ingredient.class?我是否也应该为这些类添加 @Entity 注释?我应该创建一个StepDatabase 和一个IngredientDatabase 吗?离线时是否也需要能够访问我的Recipes

【问题讨论】:

    标签: java android database pojo android-room


    【解决方案1】:

    我是否也应该保存我的每个 Step.class 和 Ingredient.class 的数据库。我应该创建一个 StepDatabase 和一个 IngredientDatabase 吗?

    当然没有。您不会为每个实体创建数据库,而是为每个实体创建一个表。在大多数应用中,一个数据库就足够了。

    传统上,SQL 数据库(本质上是关系数据库)应该强制执行normalization rules,尤其是在服务器上的企业系统中。简而言之,规范化规则指的是对关系数据库设计的一系列重构,其方式是将每个实体提取到其自己的表中,并在父表中使用外键。然后,您必须使用带有 JOIN 的 SQL SELECT 来将数据放在一起。

    话虽如此,打破移动应用程序的规范化规则并通过存储嵌套实体(在您的情况下为成分)来保持数据模型尽可能简单是很常见的,并将它们存储为 JSON 字符串或任何有意义的内容便于您在代码中处理。

    总而言之,您目前拥有的东西似乎非常好。只要它简化了您的代码 - 就去做吧。据我所知,Room 不支持 JOIN,但有something pretty close

    有一个很好的article on Medium 与 Room 讨论高级主题。

    【讨论】:

      【解决方案2】:

      是的,在我看来,首先为每个表声明一个模型是一个好习惯,是的,每个模型都应该包含 @Entity 注释,告诉休眠您正在映射的是来自数据库的表。

      【讨论】:

      • 这个问题与Hibernate无关。 @Entity 注解是指 Room ORM。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多