Room是在SQLite的基础上进行ORM封装。在使用上类似于JPA,不需要写太多的sql。准备,导入依赖//roomdefroom_version="2.4.2"implementation"androidx.room:room-runtime:$room_version"annotationProcessor"androidx.room:room-compiler:$room_version"//implementation"androidx.room:room-rxjava2:$room_version"//实现"androidx.room:room-rxjava3:$room_version"//实现"androidx.room:room-guava:$room_version"//测试实现"androidx.room:room-testing:$room_version"//implementation"androidx.room:room-paging:2.5.0-alpha01"关键注解说明1.@Database:房间数据库对象。该类需要继承自RoomDatabase,通过Room.databaseBuilder()结合单例设计模式完成数据库的创建。我们创建的Dao对象在这里以抽象方法的形式返回,只需要一行代码。实体:指定数据库有哪些表。version:指定数据库版本号。后续的数据库升级都是根据版本号来判断的。2.@Entity:这个类是和Room中的表相关联的。tableName属性可以为表设置名称,如果不设置,表名与类名相同。3、@PrimaryKey:用于指定字段作为表的主键。4、@ColumnInfo:设置存储在数据库表中的字段名称,并指定字段的类型;默认字段名与属性名相同5.@Ignore:忽略该字段1.使用步骤1创建一个实体类,对应数据库中的一张表,使用注解@Entity2.创建Dao接口用于操作数据的类,使用注解@Dao;不需要实现,框架在编译时会自动生成一个实现类3.创建数据库对象Database,继承RoomDatabase,使用单个ExampleModeReturnExample4.在Activity中使用时,Room数据操作必须异步执行线程,所以在Activity中使用线程池执行,或者使用RxJava切换线程。使用代码示例1.创建一个实体类,对应数据库中的一张表,使用注解@Entity@EntitypublicclassPerson{//主键,自增长@PrimaryKey(autoGenerate=true)privateintid;私有字符串名称;私人字符串性别;privateintage;}2.创建一个操作Data的Dao接口类,使用注解@Dao;不需要实现,框架会自动生成实现类@DaopublicinterfacePersonDao{//insert@InsertvoidinsertPersons(Person...persons);//修改@UpdatevoidupdatePersons(Person...persons);//删除所有@Query("deletefromPerson")voiddeleteAllPersons();//删除指定实体@DeletevoiddeletePersons(Person...persons);//Delete@Query("deletefromPersonwhereidin(:ids)")voiddeleteByIds(int...ids);//基于id的查询@Query("select*fromPersonwhereidin(:ids)")ListselectByIds(int...ids);//查询所有@Query("select*fromPersonorderbyiddesc")ListselectAllPersons();}3.创建一个databaseObjectDatabase,继承自RoomDatabase,使用单例模式返回实例@Database(entities={Person.class},version=1)publicabstractclassAppDatabaseextendsRoomDatabase{publicabstractPersonDaopersonDao();privatevolatilestaticAppDatabaseinstance;publicstaticAppDatabasegetInstance(Contextcontext){if(instance==null){synchronized(DBHelper.class){if(instance==null){instance=Room.databaseBuilder(context,AppDatabase.class,"person.db").build();}}}returninstance;}}4.Activity中使用Room数据的操作必须在异步线程中进行,所以在Activity中使用线程池执行ExecutorServicepool=Executors.newCachedThreadPool();//插入数据publicvoidinsertRoom(Viewview){AppDatabasedb=AppDatabase.getInstance(getApplicationContext());pool.execute(()->{PersonDaodao=db.personDao();Personp1=newPerson("用户1","男",18);Personp2=newPerson("用户2","男",28);Personp3=newPerson("用户3","男",38);dao.insertPersons(p1,p2,p3);});}//查询数据publicvoidqueryRoom(Viewview){AppDatabasedb=AppDatabase.getInstance(getApplicationContext());pool.execute(()->{PersonDaodao=db.personDao();Listlist=dao.selectAllPersons();list.forEach(p->Log.d("test",p.toString()));});}//根据id查询publicvoidqueryRoomById(Viewview){AppDatabasedb=AppDatabase.getInstance(getApplicationContext());pool.execute(()->{PersonDaodao=db.personDao();Listlist=dao.selectByIds(3,4);list.forEach(p->Log.d("test",p.toString()));});}//删除publicvoiddeleteRoom(Viewview){AppDatabasedb=AppDatabase.getInstance(getApplicationContext());pool.execute(()->{PersonDaodao=db.personDao();dao.deleteByIds(1,2);});}2.类型转换器SQLite支持null,integer,real,text,blob5其实,SQLite也接受varchar、char、decimal等数据类型,但在运行或存储时会被转换成对应的5种数据类型。因此,各种类型的数据都可以存储在除了上述基本类型之外的任何字段之外,如何存储其他对象,如Date、BigDecimal、Json?Room为我们提供了非常方便的类型转换功能。@TypeConverter,定义类型转换静态方法@TypeConverters,定义一个包含一组转换方法的class类1,创建一个类型转换类型,例如Date和Long互换使用注解@TypeConverter声明具体的转换方法,每个方法都必须包含一个参数,并且必须有一个返回值。公共类DateConverter{@TypeConverterpublicstaticDatetoDate(LongdateLong){返回dateLong==null?空:新日期(dateLong);}@TypeConverterpublicstaticLongfromDate(Datedate){返回日期==null?null:日期.getTime();}}2.在创建的转换器类上使用注解@TypeConverters({DateConverter.class}),那么实体类中的所有Date属性都会转换为Long存储,查询时取出,会自动从Long转换为日期显示。注意:@TypeConverters放在元素属性上,Class、Dao、Database放在元素属性上。只对改变属性有效,放在实体类上。它对类中的所有元素都有效,放在Dao上。它对Dao的所有方法都有效。Database,对Database和所有Daos的所有实体都有效为了避免混淆,一般建议只在Entity或属性上定义转换器@Entity@TypeConverters({DateConverter.class})publicclassBsGoods{privatestaticfinallongserialVersionUID=1122172437556010779L;//主键@PrimaryKeyprivateLongid;私有日期创建日期;私人日期更新日期;...}其他类型转换示例,BigDecimal到String。如果是JavaBean等复杂对象,可以转成Json字符串存储。公共类BigDecimalConverter{@TypeConverterpublicstaticStringtoStr(BigDecimaldecimal){返回小数==null?null:decimal.toString();}@TypeConverterpublicstaticBigDecimaltoDecimal(Stringstr){returnstr==null?null:新的BigDecimal(str);}}3.结合RxJava,在Activity中使用,更新界面UI元素Android界面UI元素更新必须在主线程中执行,而Room的数据查询只能通过异常线程处理。那么如何将查询到的数据更新到页面控件中呢?这里可以结合RxJava实现流式操作和离线切换!示例代码查询所有产品数据并显示在页面控件上。控件使用自定义的TableView,暂不展开。这里只展示数据查询和展示。1.在Database类中定义查询方法,传入回调函数publicvoidselectAll(Consumer>fun){BsGoodsDaodao=bsGoodsDao();Observable.just("select").map(s->dao.selectAll()).subscribeOn(Schedulers.io())//为上面的操作分配一个异步线程。observeOn(AndroidSchedulers.mainThread())//将Android主线程分配给端点。subscribe(newObserver>(){@OverridepublicvoidonSubscribe(@NonNullDisposabled){}@OverridepublicvoidonNext(@NonNullListbsGoods){fun.accept(bsGoods);}@OverridepublicvoidonError(@NonNullThrowablee){}@OverridepublicvoidonComplete(){}});}2.在Activity中使用,传入回调函数更新接口UIprivatevoidinitializeTableViewLocal(){BsGoodsDatabasedb=BsGoodsDatabase.getInstance(getContext());db。getColumnHeaderList(),tableViewModel.getRowHeaderList(),tableViewModel.getCellList());});}