Room在项目中的使用

介绍JetPack中的Room

Room在项目中的使用

本篇已Java为主要语言

添加依赖

1
2
implementation "androidx.room:room-runtime:2.2.5"
annotationProcessor "androidx.room:room-compiler:2.2.5"

使用

接下来我就以保存历史为例,先介绍一下各个注释的意思

注释名称 意思
@Entity 代表数据库中某个表的实体类。
@Ignore 代表无用的构造方法
@PrimaryKey() 代表主键的意思,是必须要有的
@Database 包含数据库持有者,并作为与应用持久关联数据的底层连接的主要访问点
  1. 创建 HistoryBean

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    @Entity
    public class HistoryBean {

    public HistoryBean() {

    }

    @Ignore
    public HistoryBean(int id, String name, String address, String state) {
    this.EquipmentId = id;
    this.EquipmentName = name;
    this.EquipmentAddress = address;
    this.EquipmentState = state;
    }

    @PrimaryKey()
    private int EquipmentId;
    private String EquipmentName;
    private String EquipmentAddress;
    private String EquipmentPersonnel;
    private String EquipmentState;

    public int getEquipmentId() {
    return EquipmentId;
    }

    public void setEquipmentId(int equipmentId) {
    EquipmentId = equipmentId;
    }

    public String getEquipmentName() {
    return EquipmentName;
    }

    public void setEquipmentName(String equipmentName) {
    EquipmentName = equipmentName;
    }

    public String getEquipmentAddress() {
    return EquipmentAddress;
    }

    public void setEquipmentAddress(String equipmentAddress) {
    EquipmentAddress = equipmentAddress;
    }

    public String getEquipmentPersonnel() {
    return EquipmentPersonnel;
    }

    public void setEquipmentPersonnel(String equipmentPersonnel) {
    EquipmentPersonnel = equipmentPersonnel;
    }

    public String getEquipmentState() {
    return EquipmentState;
    }

    public void setEquipmentState(String equipmentState) {
    EquipmentState = equipmentState;
    }
    }

  1. 创建一个数据库管理类 (AppDatabase)继承 RoomDatabase

    1
    2
    3
    4
    5
    6
    @Database(entities = {HistoryBean.class}, version = 1)
    public abstract class AppDatabase extends RoomDatabase {

    public abstract HistoryDao historyDao();

    }
  2. 然后在创建一个数据库操作接口 (HistoryDao)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    @Dao
    public interface HistoryDao {
    /**
    * 插入数据
    *
    * @param historyBean
    */
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertAll(HistoryBean historyBean);

    /**
    * 删除数据
    */
    @Query("DELETE FROM historybean")
    void deleteAll();

    /**
    * 更新数据(传入不一样的数据,将会自动将不一样的数据替换旧数据)
    *
    * @param historyBean
    */
    @Update
    void updateUsers(HistoryBean historyBean);

    /**
    * 查询数据
    *
    * @return
    */
    @Query("SELECT * FROM HistoryBean")
    LiveData<List<HistoryBean>> getAll();
    }
  1. 接下来就是在Activity/Fragment中使用,因为在主线程中是不允许进行数据库操作的,会阻塞线程,所以必须要在子线程中来操作数据库。下面的代码就是使用AsyncTask来进行子线程操作

    那么下面将创建一个数据库操作类,用来方便进行数据库操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    public class DaoOperation {
    private static AppDatabase db;
    private static DaoOperation instance;

    //这里将DaoOpertaion设置为单例模式,因为会在各种地方使用
    public static DaoOperation getDatabase(Context context) {
    if (instance == null) {
    synchronized (AppDatabase.class) {
    if (instance == null) {
    db = MyApplication.getDatabase(context);
    instance = new DaoOperation();
    }
    }
    }
    return instance;
    }

    //这里是对外开放接口
    public void insertHistory(HistoryBean historyBean) {
    new insertHistory(historyBean).execute(historyBean);
    }

    public void dellHistory() {
    new dellHistory().execute();
    }

    public void upHistory(HistoryBean historyBean) {
    new upHistory(historyBean).execute(historyBean);
    }


    //以下是内部实现过程
    /**
    * 插入历史
    */
    private static class insertHistory extends AsyncTask<HistoryBean, Void, Void> {
    private final HistoryBean historyBean;

    public insertHistory(HistoryBean historyBean) {
    this.historyBean = historyBean;
    }

    @Override
    protected Void doInBackground(HistoryBean... historyBeans) {
    db.historyDao().insertAll(historyBean);
    return null;
    }
    }

    /**
    * 删除全部历史
    */
    private static class dellHistory extends AsyncTask<Void, Void, Void> {

    public dellHistory() {
    }

    @Override
    protected Void doInBackground(Void... voids) {
    db.historyDao().deleteAll();
    return null;
    }
    }

    /**
    * 更改历史(基本用不上)
    */
    private static class upHistory extends AsyncTask<HistoryBean, Void, Void> {
    private final HistoryBean historyBean;

    public upHistory(HistoryBean historyBean) {
    this.historyBean = historyBean;

    }

    @Override
    protected Void doInBackground(HistoryBean... historyBeans) {
    db.historyDao().updateUsers(historyBean);
    return null;
    }
    }

    关于AsyncTast的使用,其他篇幅就已经讲过了,这里就并进行讲解了 关于Android多线程操作

  2. 最后在Activty/Fragment中使用(展示经常使用的插入和删除)

    插入

    1
    DaoOperation.getDatabase(this).insertHistory(new HistoryBean(id,name, address,state));

    删除

    1
    DaoOperation.getDatabase(this).dellHistory();
  3. 展示不一样的数据库查询(下面的代码HistoryModel是因为我当前项目使用的Mvvm的设计模式,我将所以数据操作都放在Model中了)

    因为上面设置查询的结果为LiveData,也就是可观察

    1
    2
    3
    4
    5
    6
    7
    8
    HistoryModel mHistoryModel = new ViewModelProvider(this).get(HistoryModel.class);
    mHistoryModel.getHistory(this).observe(this, new Observer<List<HistoryBean>>() {
    @Override
    public void onChanged(List<HistoryBean> historyBeans) {
    //这里我是将查询到的数据传入设配器中
    adapter.loadMore(historyBeans);
    }
    });

    关于使用LiveData的好处有多,比如

    • 会观察当前引用类的生命周期,只会在生命周期内进行操作
    • 不会造成内存泄漏
    • 一旦数据发送变化,将立马通知