Room基本使用

官方教程

一、配置依赖

dependencies {
    
    
    def room_version = "2.3.0"

    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"

    // 可选 - RxJava2 support for Room
    implementation "androidx.room:room-rxjava2:$room_version"

    // 可选 - RxJava3 support for Room
    implementation "androidx.room:room-rxjava3:$room_version"

    // 可选 - Guava support for Room, including Optional and ListenableFuture
    implementation "androidx.room:room-guava:$room_version"

    // 可选 - Test helpers
    testImplementation "androidx.room:room-testing:$room_version"

    // 可选 - Paging 3 Integration
    implementation "androidx.room:room-paging:2.4.0-alpha05"
}

如果是kotlin项目可以添加kotlin-kapt插件,然后更改annotationProcessor为kapt,示例如下

plugins {
    
    
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
}
...
dependencies {
    
    
    def room_version = "2.3.0"

    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    implementation "androidx.room:room-ktx:$room_version"
    }

二、创建表

Room是一个对象一张表,所以在要存储的bean上添加@Entity,框架就会自动建表。示例如下

@Entity(tableName = "history",primaryKeys = {
    
    "uid","vid"})
public class HistoryBean {
    
    
    private int uid;
    @NonNull
    private String vid = "";
    @ColumnInfo(name = "title", typeAffinity = ColumnInfo.TEXT)
    private String title;
    @Ignore
    ...
    }

tableName属性可以为该表设置名字,如果不设置,则表名与类名相同。
@ColumnInfo标签可用于设置该字段存储在数据库表中的名字并指定字段的类型。
@Ignore顾名思义,数据库忽略该字段

三、定义表操作(增删改查)

新建一个接口,添加@Dao注解,然后定义增删改查的方法,框架会自动实现,示例如下

@Dao
public interface HistoryDao {
    
    

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    public void setHistory(HistoryBean historyBean);

    @Update
    public void updateHistory(HistoryBean historyBean);

    @Delete
    public void deleteHistory(HistoryBean historyBean);

    @Query("select * from history order by viewTime desc")
    public List<HistoryBean> getAllHistory();

    @Query("select * from history where uid = :uid and vid = :vid")
    public HistoryBean findHistory(int uid,String vid);
}

四、创建数据库

@Database(entities = {
    
    HistoryBean.class},version = 1,exportSchema = false)
@TypeConverters({
    
    AppBaseConverter.class})
public abstract class AppBaseDatabase extends RoomDatabase {
    
    
    private static class AppBaseDatabaseHolder {
    
    
        private static final AppBaseDatabase instance = Room.databaseBuilder(BIPApp.getInstance(),AppBaseDatabase.class,"baseDb").fallbackToDestructiveMigration().build();
    }

    public static AppBaseDatabase getInstance() {
    
    
        return AppBaseDatabase.AppBaseDatabaseHolder.instance;
    }
    abstract HistoryDao getHistoryDao();
}

@TypeConverters注解是可选的,用于转换数据库无法识别的数据类型,比如自定义类,示例如下

public class AppBaseConverter {
    
    
    @TypeConverter
    public String List2String(List<VideoListBean> data){
    
    
        return new Gson().toJson(data);
    }

    @TypeConverter
    public List<VideoListBean> String2List(String data){
    
    
        return new Gson().fromJson(data,new TypeToken<List<VideoListBean>>(){
    
    }.getType());
    }
}

完成上面操作后就可以正常使用了,比如

AppBaseDatabase.getInstance().getHistoryDao().getAllHistory();

五、迁移数据库

当表结构变化或者增加新的表时需要迁移数据库,比如有版本1升级到版本2,增加了一张表,那么需要在entities里加上表类,更新版本号。示例如下

@Database(entities = {
    
    HistoryBean.class, DownloadInfoBean.class}, version = 2)

增加了DownloadInfoBean然后更新了version。接着定义一个Migration,示例如下

    static final Migration MIGRATION1_2 = new Migration(1, 2) {
    
    
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
    
    
            database.execSQL("CREATE TABLE IF NOT EXISTS `download` (`mediaId` TEXT NOT NULL, `title` TEXT, `sourceUrl` TEXT, `downloadState` INTEGER NOT NULL, `localPath` TEXT, `contentLength` INTEGER NOT NULL, `cover` TEXT, `downloadUrl` TEXT, `coverPortrait` INTEGER NOT NULL, `duration` INTEGER NOT NULL, `downloadTime` INTEGER NOT NULL, `sourceName` TEXT, `videoData` TEXT, `selectSourceIndex` INTEGER NOT NULL, `downloadTargetPosition` INTEGER NOT NULL, `downloadingProgress` INTEGER NOT NULL, PRIMARY KEY(`mediaId`))");
        }
    };

上面的数字1和2对应版本号,表示数据库由1升级到2时会触发这个Migration。可以跨版本升级(比如你定义了1~3的Migration,在从1升级到3时就会调用他,否则依次调用1-2,2-3)。上面就是新建了DownloadInfoBean对应的表。建表语句可以通过设置exportSchema=true然后在项目build.gradle文件指定schema导出位置,就能看到导出的schema。示例如下

    defaultConfig {
    
    
        
        ...
        
        javaCompileOptions {
    
    
            annotationProcessorOptions {
    
    
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }

最后在获取数据库实例时通过addMigrations传入Migration,示例如下

        private static final AppBaseDatabase instance = Room.databaseBuilder(BIPApp.getInstance(), AppBaseDatabase.class, "appDb").addMigrations(MIGRATION1_2).build();

如果没有配置对应的Migration,当配置了fallbackToDestructiveMigration时会清空数据库数据,如果连fallbackToDestructiveMigration都没配置则会发生崩溃。

自动迁移

版本2.4.0后提供了一个自动迁移的API,就不细讲了放一下官方示例代码,感兴趣的自行了解(需要注意使用自动迁移exportSchema一定要是true)。

@Database(
   version = MusicDatabase.LATEST_VERSION,
   entities = [
       Song.class,
       Artist.class
   ],
   autoMigrations = [
       @AutoMigration (
           from = 1,
           to = 2
       ),
       @AutoMigration (
           from = 2,
           to = 3,
           spec = MusicDatabase.MyExampleAutoMigration::class
       )
   ],
   exportSchema = true
)
abstract class MusicDatabase  : RoomDatabase() {
    
    
   const val LATEST_VERSION = 3

   @DeleteTable(deletedTableName = "Album")
   @RenameTable(fromTableName = "Singer", toTableName = "Artist")
   @RenameColumn(
       tableName = "Song",
       fromColumnName = "songName",
       toColumnName = "songTitle"
    )
   @DeleteColumn(fromTableName = "Song", deletedColumnName = "genre")
   class MyExampleAutoMigration : AutoMigrationSpec {
    
    
       @Override
       override fun onPostMigrate(db: SupportSQLiteDatabase) {
    
    
           // Invoked once auto migration is done
       }
    }
}

猜你喜欢

转载自blog.csdn.net/Welcome_Word/article/details/120725889