如何预填充我的 Room 数据库?
How do I prepopulate my Room database?
这是我第一次试验 Room 数据库,我想用 20 个用户对象预填充数据库。但是我使用的代码每次 运行s 都会向现有列表添加 20 个用户。我如何防止它这样做?
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
public abstract DataExchange dataExchange();
public static AppDatabase getAppDatabase(final Context context){
if (INSTANCE == null){
INSTANCE = Room.databaseBuilder(context,
AppDatabase.class,
"User_Database")
.addCallback(new Callback() {
@Override
public void onCreate(@NonNull final SupportSQLiteDatabase db) {
super.onCreate(db);
Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
@Override
public void run() {
getAppDatabase(context).dataExchange().insert(User.populate());
}
});
}
})
.build();
}
return INSTANCE;
}
public static void destroyInstance(){
INSTANCE = null;
}
这是用户 class:
@Entity(tableName = "user_table")
public class User{
public User(String name){
setName(name);
}
@PrimaryKey(autoGenerate = true)
private int uid;
@ColumnInfo(name = "Username")
private String name;
public String getName() {
return name;
}
public void setUid(int uid) {
this.uid = uid;
}
public void setName(String name) {
this.name = name;
}
public static User[] populate(){
User[] ar = new User[20];
for(int i=0; i<20;i++){
ar[i] = new User("USER "+(i+1));
}
return ar;
}
}
此外,我从中获取代码的地方在 运行() 中有一个 getInstance(context) 而不是 getAppDatabase(context)。我更改它是因为在我不知道的 5 个库中发现了 getInstance。
这是数据交换:
@Dao
public interface DataExchange {
@Query("SELECT * FROM user_table")
List<User> getAll();
@Query("SELECT * FROM user_table where username LIKE :name ")
User findByName(String name);
@Query("SELECT COUNT(*) from user_table")
int countUsers();
@Update
void update(User user);
@Insert
void insertAll(User... users);
@Delete
void delete(User user);
}
第 1 步:
为您的实体添加主键,建议在您的场景中使用 int。例如:ID 为 1 的用户在您的数据库中是唯一的。
@Entity
public class User {
@PrimaryKey
public int id;
}
https://developer.android.com/training/data-storage/room/defining-data
第 2 步:
为 id 变量赋值。我推荐通过Userclass的构造函数来赋值(主要是防止它为0,或者防止你后面在一个setter中忘记赋值)
第 3 步:
在您的@Insert 中定义冲突策略(在您的 DAO class 中)。当数据库尝试添加另一个 id = 1 的用户时,您希望它做什么?您要删除旧用户吗?直接忽略?
@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
https://developer.android.com/reference/android/arch/persistence/room/Insert
此外,我 100% 确定您在猜测代码。看看官方文档就知道了。
我建议只复制您使用 DB Browser for SQLite 创建的数据库。这是进行预填充的最简单方法。您只需在您的应用程序中创建 Assets 文件夹,添加文件夹数据库,然后复制您的数据库。
在创建数据库的单例 class 中,只需添加 createFromAsset() 方法,您就拥有了预填充的数据库。照片在 link.
上
https://i.stack.imgur.com/Q5o4v.jpg
另外在这篇文章中描述的非常好。
https://medium.com/androiddevelopers/packing-the-room-pre-populate-your-database-with-this-one-method-333ae190e680
这是我第一次试验 Room 数据库,我想用 20 个用户对象预填充数据库。但是我使用的代码每次 运行s 都会向现有列表添加 20 个用户。我如何防止它这样做?
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
private static AppDatabase INSTANCE;
public abstract DataExchange dataExchange();
public static AppDatabase getAppDatabase(final Context context){
if (INSTANCE == null){
INSTANCE = Room.databaseBuilder(context,
AppDatabase.class,
"User_Database")
.addCallback(new Callback() {
@Override
public void onCreate(@NonNull final SupportSQLiteDatabase db) {
super.onCreate(db);
Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
@Override
public void run() {
getAppDatabase(context).dataExchange().insert(User.populate());
}
});
}
})
.build();
}
return INSTANCE;
}
public static void destroyInstance(){
INSTANCE = null;
}
这是用户 class:
@Entity(tableName = "user_table")
public class User{
public User(String name){
setName(name);
}
@PrimaryKey(autoGenerate = true)
private int uid;
@ColumnInfo(name = "Username")
private String name;
public String getName() {
return name;
}
public void setUid(int uid) {
this.uid = uid;
}
public void setName(String name) {
this.name = name;
}
public static User[] populate(){
User[] ar = new User[20];
for(int i=0; i<20;i++){
ar[i] = new User("USER "+(i+1));
}
return ar;
}
}
此外,我从中获取代码的地方在 运行() 中有一个 getInstance(context) 而不是 getAppDatabase(context)。我更改它是因为在我不知道的 5 个库中发现了 getInstance。
这是数据交换:
@Dao
public interface DataExchange {
@Query("SELECT * FROM user_table")
List<User> getAll();
@Query("SELECT * FROM user_table where username LIKE :name ")
User findByName(String name);
@Query("SELECT COUNT(*) from user_table")
int countUsers();
@Update
void update(User user);
@Insert
void insertAll(User... users);
@Delete
void delete(User user);
}
第 1 步:
为您的实体添加主键,建议在您的场景中使用 int。例如:ID 为 1 的用户在您的数据库中是唯一的。
@Entity
public class User {
@PrimaryKey
public int id;
}
https://developer.android.com/training/data-storage/room/defining-data
第 2 步:
为 id 变量赋值。我推荐通过Userclass的构造函数来赋值(主要是防止它为0,或者防止你后面在一个setter中忘记赋值)
第 3 步:
在您的@Insert 中定义冲突策略(在您的 DAO class 中)。当数据库尝试添加另一个 id = 1 的用户时,您希望它做什么?您要删除旧用户吗?直接忽略?
@Insert(onConflict = OnConflictStrategy.REPLACE)
public void insertUsers(User... users);
https://developer.android.com/reference/android/arch/persistence/room/Insert
此外,我 100% 确定您在猜测代码。看看官方文档就知道了。
我建议只复制您使用 DB Browser for SQLite 创建的数据库。这是进行预填充的最简单方法。您只需在您的应用程序中创建 Assets 文件夹,添加文件夹数据库,然后复制您的数据库。 在创建数据库的单例 class 中,只需添加 createFromAsset() 方法,您就拥有了预填充的数据库。照片在 link.
上https://i.stack.imgur.com/Q5o4v.jpg
另外在这篇文章中描述的非常好。 https://medium.com/androiddevelopers/packing-the-room-pre-populate-your-database-with-this-one-method-333ae190e680