数据库的基本使用

添加依赖

    //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;
    }
 	......
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐