我有 3 个 POJO 类。 Recipe
, Ingredient
和 Step
.
我希望能够在离线时浏览我的食谱,所以我决定使用 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);
}
我的问题:保存 List<Step>
后和 List<Ingredient>
作为Strings
使用 Converters
类,我还应该保存我的每个 Step.class 和 Ingredient.class 的数据库吗?我应该包括 @Entity
吗?这些类也有注解吗?我应该做一个StepDatabase
吗?和一个 IngredientDatabase
?是否还需要能够访问我的 Recipes
什么时候离线?
最佳答案
should I also save a database of each of my Step.class and Ingredient.class. Should I make a StepDatabase and an IngredientDatabase?
当然不是。您不是为每个实体创建数据库,而是为每个实体创建一个表。在大多数应用程序中,一个数据库就足够了。
传统上,SQL 数据库(本质上是关系数据库)应该强制执行 normalization rules ,尤其是在服务器上的企业系统中。简而言之,规范化规则是指对关系数据库设计的一系列重构,其中每个实体都被提取到其自己的表中,并在父表中使用外键。然后,您必须使用带有 JOIN 的 SQL SELECT 来收集数据。
话虽如此,打破移动应用程序的规范化规则并通过存储嵌套实体(在您的情况下为成分)并将它们存储为 JSON 字符串或任何有意义的方式来保持数据模型尽可能简单是很常见的便于您在代码中处理。
总而言之,您目前拥有的东西看起来非常好。只要它能简化您的代码——就去做吧。据我所知,Room 不支持 JOIN,但是有 something pretty close .
有一个很好的article on Medium与 Room 讨论高级主题。
关于java - 将我的模型对象存储在房间数据库中的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48357049/