Android(安卓)Jetpack Components of Room 学习笔记
关于 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 进行增删改查操作了。
更多相关文章
- Retrofit 基本用法
- Android(安卓)Sqite数据库
- android 使用SQLite对数据进行增删改查、访问
- Android(安卓)MediaProvider数据库模式
- Android使用SharedPreferences实现登录帐号和密码的保存方法简介
- Android(安卓)SQLiteOpenHelper使用和源码详解
- Annotation Processor在Android下的应用入门
- Android(安卓)Mediascanner实现机制
- 2.1……Android中的单位简介