关于 Room,网上优秀的文章太多了。本文我只从自己的角度介绍 Room 使用,相信对你也够用了的。

Room Google 文档:https://developer.android.google.cn/topic/libraries/architecture/room

一、环境配置:

// room 配置    implementation "android.arch.persistence.room:runtime:1.1.1"    implementation "android.arch.persistence.room:rxjava2:1.1.1"    annotationProcessor "android.arch.persistence.room:compiler:1.1.1"

如果是 androidx,则参考官网的配置。

 

二、Room 结构简介:

Room 组件的三个核心部分,分别是:

1、Entity 数据实体类,同时映射为数据库中的表结构。

2、Dao 数据库表的增删改查操作类。

3、Database SqLite 数据库对象获取和管理类。

 

三、Entity 注解简介:

Entity 是注解。使用 Entity 标记的类,将会被映射为数据库中的表。以话题赛事提醒需求为例说明:

@Entity(tableName = "topic_match_table",        primaryKeys = {"topic_id", "match_id"},        indices = {                @Index(value = {"topic_id"}),                @Index(value = {"topic_id", "match_id"})        })@Keeppublic class MatchEntity implements Parcelable {    public MatchEntity() {    }    @Ignore    public MatchEntity(int matchId) {        this.mMatchId = matchId;    }    @Ignore    public MatchEntity(String topicId, int matchId, String teamA, String teamB, long timeStart) {        this.mTopicId = topicId;        this.mMatchId = matchId;        this.mTeamA = teamA;        this.mTeamB = teamB;        this.mTimeStart = timeStart;    }    // 话题 id    @ColumnInfo(name = "topic_id")    @NonNull    public String mTopicId;    // 赛事 id    @ColumnInfo(name = "match_id")    @NonNull    public int mMatchId;    // 赛队 A    @ColumnInfo(name = "team_a")    public String mTeamA;    // 赛队 B    @ColumnInfo(name = "team_b")    public String mTeamB;    // 闹钟开始时间    @ColumnInfo(name = "time_start")    public long mTimeStart;    @Ignore    public PendingIntent mPendingIntent;    // 参考 AlarmManager.RTC_WAKEUP    // ELAPSED 开头的代表系统运行逝去的时间,RTC 开头的是世界时钟    // 以WAKEUP结尾的类型能够唤醒设备    // public static final int RTC_WAKEUP = 0;    // public static final int RTC = 1;    // public static final int ELAPSED_REALTIME_WAKEUP = 2;    // public static final int ELAPSED_REALTIME = 3;    // 闹钟类型    @Ignore    public int mAlarmManagerType = AlarmManager.RTC_WAKEUP;    @Override    public String toString() {        String name = MatchEntity.class.getCanonicalName();        if (name == null) {            return super.toString();        }        String timeString = SimpleDateFormat.getDateTimeInstance().format(new Date(mTimeStart));        return name + " -> mTopicId = " +                mTopicId +                " mMatchId = " +                mMatchId +                " mTeamA = " +                mTeamA +                " mTeamB = " +                mTeamB +                " mTimeStart = " +                timeString;    }    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeString(this.mTopicId);        dest.writeInt(this.mMatchId);        dest.writeString(this.mTeamA);        dest.writeString(this.mTeamB);        dest.writeLong(this.mTimeStart);        dest.writeParcelable(this.mPendingIntent, flags);        dest.writeInt(this.mAlarmManagerType);    }    protected MatchEntity(Parcel in) {        this.mTopicId = in.readString();        this.mMatchId = in.readInt();        this.mTeamA = in.readString();        this.mTeamB = in.readString();        this.mTimeStart = in.readLong();        this.mPendingIntent = in.readParcelable(PendingIntent.class.getClassLoader());        this.mAlarmManagerType = in.readInt();    }    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {        @Override        public MatchEntity createFromParcel(Parcel source) {            return new MatchEntity(source);        }        @Override        public MatchEntity[] newArray(int size) {            return new MatchEntity[size];        }    };}

1、类声明处使用了 @Entity 注解。tableName 属性表示 MatchEntity 类映射到数据中的表名为 topic_match_table。primaryKeys 属性表示创建了一个联合主键。indices 属性值表明创建了 2 个索引。

2、属性和构造函数上使用了 @Ignore 注解。除了无参的构造函数外,其他所有的构造函数都需要添加此注解。不想被映射到数据库表字段的属性需要添加此注解。

3、在属性上使用了 @ColumnInfo 注解,表示此属性映射到数据库表的字段名。如果不添加此注解,则类属性名和表字段名相同。

4、设置为主键的属性,需要添加 @NonNull 注解。

5、也可以直接在某属性上使用 @PrimaryKey 注解声明主键。

以上只是 Entity 部分内容,掌握了这么多基本够用。

 

四、Dao 注解简介:

使用 Dao 注解标注的接口,承载着对 Entity 增删改查的使命。

@Daopublic interface MatchDao {    @Query("SELECT match_id FROM topic_match_table WHERE topic_id = :topicId")    int[] getTopicMatchesId(String topicId);    @Query("SELECT * FROM topic_match_table")    List getAllMatches();    @Insert(onConflict = OnConflictStrategy.REPLACE)    void insertMatch(MatchEntity... matchEntities);    @Delete    void deleteMatch(MatchEntity... matchEntities);    @Query("DELETE FROM topic_match_table WHERE topic_id = :topicId AND match_id = :matchId")    void deleteMatchById(String topicId, int matchId);}

1、@Dao 标注在接口上,忘记是否可以是抽象类了。

2、对数据库的增删改查四种操作,分别对应 @Insert / @Delete / @Update / @Query 4 个注解。

3、灵活运用。比喻删除操作也可以使用 @query 注解:@Query("DELETE FROM topic_match_table WHERE topic_id = :topicId AND match_id = :matchId")

4、@Insert 注解的 onConflict 参数含义是:当添加发生冲突时,直接替换旧数据。

5、更多信息可以参考 Room 组件注解的声明说明。

 

 

五、Database 注解简介:

Database 注解,标注配置一些数据库的信息。

@Database(entities = {MatchEntity.class}, version = MatchDatabase.DB_VERSION, exportSchema = false)public abstract class MatchDatabase extends RoomDatabase {    // you need update this version value when you update database structure    public static final int DB_VERSION = 1;    public static final String DB_NAME = "topic_match.db";    public abstract MatchDao getMatchDao();}

1、注意,自定义抽象类 MatchDatabase 继承RoomDatabase 类。

2、@Database 注解标注在 MatchDatabase 抽象类上,表示此数据库的名称、数据库中有哪些表、是否导出历史数据和表结构的 json 数据。

3、MatchDatabase 需要提供一个公共的抽象的方法,返回某 Entity 的操作类,比喻 MatchDao。

 

 

六、Room 使用简介:

public class MatchRoomHelper {    private static MatchDatabase MATCH_DATABASE;    private static MatchRoomHelper INSTANCE;    private MatchRoomHelper(Context applicationContext) {        MATCH_DATABASE = Room.databaseBuilder(applicationContext, MatchDatabase.class, MatchDatabase.DB_NAME)                .allowMainThreadQueries() // 允许在主线程执行数据库操作                .build();    }    public synchronized static MatchRoomHelper getInstance(Context applicationContext) {        if (INSTANCE == null) {            INSTANCE = new MatchRoomHelper(applicationContext);        }        return INSTANCE;    }    public List getAllMatches() {        return MATCH_DATABASE.getMatchDao().getAllMatches();    }    public int[] getTopicMatchesId(String topicId) {        return MATCH_DATABASE.getMatchDao().getTopicMatchesId(topicId);    }    public synchronized void insertMatch(MatchEntity... matchEntities) {        MATCH_DATABASE.getMatchDao().insertMatch(matchEntities);    }    public synchronized void deleteMatch(MatchEntity... matchEntities) {        MATCH_DATABASE.getMatchDao().deleteMatch(matchEntities);    }}

1、MatchDatabase 是实际的数据库配置承载类,可以使用 Room.databaseBuilder()创建数据库对象。参考 MatchRoomHelper 构造函数代码。

2、注意 allowMainThreadQueries() 配置,表示是否允许在主线程执行数据库操作。默认是不允许的,如果不允许,则在 UI 线程执行数据库操作会崩溃。

3、MatchDatabase 数据库对象不建议重复创建,或使用单例模式?!

4、通过 MatchRoomHelper 获取单例的 MatchDatabase 数据库对象,再获取 MatchDao 对象,就可以对对应的 Entity 进行增删改查操作了。

 

 

 

 

 

 

 

 

更多相关文章

  1. Retrofit 基本用法
  2. Android(安卓)Sqite数据库
  3. android 使用SQLite对数据进行增删改查、访问
  4. Android(安卓)MediaProvider数据库模式
  5. Android使用SharedPreferences实现登录帐号和密码的保存方法简介
  6. Android(安卓)SQLiteOpenHelper使用和源码详解
  7. Annotation Processor在Android下的应用入门
  8. Android(安卓)Mediascanner实现机制
  9. 2.1……Android中的单位简介

随机推荐

  1. Android:adb shell am命令行发送Activity
  2. IDA调试Android(安卓)so文件
  3. Android(安卓)锁屏或者home键 tcp 断开
  4. 《Android面试宝典》学习笔记(第五章:文件
  5. android 屏幕判断
  6. Android(安卓)- 按钮组件详解
  7. android 命令大全
  8. 如何将library项目打包成jar文件
  9. Android之开发BLE 详细步骤
  10. Android中shape的使用