数据库的基本使用
添加依赖
    //room
    def room_version = "2.5.0"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
创建表
 @Entity表示根据实体类创建数据表,如果有多个主键要使用primaryKeys = {}
 @ColumnInfo 表示在数据表中的名字
 @Ignore 表示不在数据表创建此字段
 @PrimaryKey 主键
@Entity
public class Word {
    @PrimaryKey
    @ColumnInfo(name = "id")
    private int id;
    @ColumnInfo(name = "word")
    private String word;
    @ColumnInfo(name = "wordCH")
    private String wordCH;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getWord() {
        return word;
    }
    public void setWord(String word) {
        this.word = word;
    }
    public String getWordCH() {
        return wordCH;
    }
    public void setWordCH(String wordCH) {
        this.wordCH = wordCH;
    }
}
创建DAO
 每一个表都对应一个dao。
@Dao
public interface WordDao {
    @Query("select * from word")
    List<Word> getAll();
    @Insert
    void insert(Word... words);
    @Query("delete from word where   wordCh = :wordCH ")
    void deleteWord(String wordCH);
}
创建数据库
 创建一个抽象类,设置要创建的数据表,数据版本,数据库名称,DAO。
 entities 表示数据库中有哪些表
@Database(entities = {Word.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {
    public static MyDatabase myDatabase;
    public static synchronized MyDatabase getInstence(Context context) {
        if (myDatabase == null) {
            myDatabase = Room.databaseBuilder(context, MyDatabase.class, "my.db")
                    .build();
        }
        return myDatabase;
    }
    /**
     * 声明dao
     * @return
     */
    public abstract WordDao getWordDao();
}
对数据库进行增删改查操作,必须要在子线程中。这里向数据库中插入了一条数据,又从数据库中进行了查寻并输出。代码如下:
        new Thread(new Runnable() {
            @Override
            public void run() {
                MyDatabase myDatabase = MyDatabase.getInstence(getApplicationContext());
                Word word = new Word();
                word.setId(1);
                word.setWord("hello");
                word.setWordCH("你好");
                myDatabase.getWordDao().insert(word);
                List<Word> wordList = myDatabase.getWordDao().getAll();
                for (Word word1 : wordList) {
                    Log.d("Word", word1.toString());
                }
            }
        }).start();
Room与LiveData、ViewMode结合使用
但数据发生变化时,总是需要启动一个线程去查询数据,这很麻烦,于是有了更好的处理方案。
 我们将获取到的List用livedata包装起来。
@Dao
public interface WordDao {
	........
    @Query("select * from word")
    LiveData<List<Word>> getAll();
}
创建WordViewModel
 AndroidViewModel 与ViewModel不同点在于有没有context。
public class WordViewModel extends AndroidViewModel {
    private MyDatabase myDatabase;
    private LiveData<List<Word>> listLiveData;
    public WordViewModel(@NonNull Application application) {
        super(application);
        WordDao wordDao = myDatabase.getWordDao();
        listLiveData = wordDao.getAll();
    }
    public LiveData<List<Word>> getListLiveData() {
        return listLiveData;
    }
}
监听数据
        wordViewModel = new ViewModelProvider(this).get(WordViewModel.class);
        wordViewModel.getListLiveData().observe(this, new Observer<List<Word>>() {
            @Override
            public void onChanged(List<Word> words) {
                
            }
        });
当对数据库进行增加、删除或者修改时,onChanged方法会被调用。
使用migration升级
当数据库添加表,或者修改字段时,需要做一些调整,对数据库进行升级。
表示数据从版本1升级到版本2
    public static Migration migration = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
        }
    };
1->3这种升级,room会判断有没有从1到3的升级方案,如果有,则直接升级;如果没有则room会按照1->2,2->3升级。
 写完Migration 需要添加。
@Database(entities = {Word.class}, version = 2)
public abstract class MyDatabase extends RoomDatabase {
    public static MyDatabase myDatabase;
    public static synchronized MyDatabase getInstence(Context context) {
        if (myDatabase == null) {
            myDatabase = Room.databaseBuilder(context, MyDatabase.class, "my.db")
                    .addMigrations(migration)
                    .build();
        }
        return myDatabase;
    }
    public static Migration migration = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
        }
    };
	.........
}
Schema文件
每次数据库升级都会生成一个Schema文件,这是一个json文件,包含了数据库的所有信息。查看它,能清楚地知道数据库每版变更的情况。
设置Schema导出路径
class RoomSchemaArgProvider implements CommandLineArgumentProvider {
    @InputDirectory
    @PathSensitive(PathSensitivity.RELATIVE)
    File schemaDir
    RoomSchemaArgProvider(File schemaDir) {
        this.schemaDir = schemaDir
    }
    @Override
    Iterable<String> asArguments() {
        // Note: If you're using KSP, you should change the line below to return
        // ["room.schemaLocation=${schemaDir.path}"]
        return ["-Aroom.schemaLocation=${schemaDir.path}"]
    }
}
android {
  
    defaultConfig {
    
		.......
        /*room数据库需要*/
        javaCompileOptions {
            annotationProcessorOptions {
                compilerArgumentProviders(
                        new RoomSchemaArgProvider(new File(projectDir, "schemas"))
                )
            }
        }
    }
}

预填充数据库createFromAsset、createFromFile
createFromFile用来作用域目录中的路径。
 createFromAsset用来传输Asset中的路径
根据数据库表创建数据库,添加数据,导出db文件,存放与Asset文件中。

@Database(entities = {Word.class}, version = 2)
public abstract class MyDatabase extends RoomDatabase {
    public static MyDatabase myDatabase;
    public static synchronized MyDatabase getInstence(Context context) {
        if (myDatabase == null) {
            myDatabase = Room.databaseBuilder(context, MyDatabase.class, "my.db")
                    .addMigrations(migration)
                    .createFromAsset("my.db")//预填充数据库
                    .build();
        }
        return myDatabase;
    }
 	......
}



















