android 开发进程 0.37 room数据存储的使用

room数据存储简介

room 是jetpack库中的一个数据持久化库,底层还是使用的SQLite的实现方式。但使用方式更加简单,原生的SQLite方法较为繁琐,room使用的是实体类和数据库表映射的方式。更为简洁易懂。  

room数据库导入

在module的gradle中添加:

    def room_version = "2.3.0" // check latest version from docs
    implementation "androidx.room:room-ktx:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"

注意kapt是在项目使用kotlin后必须添加的,且不是数据库相关代码使用kotlin才需要导入,只要项目导入了kotlin就需要引入kotlin的库,此外GitHub上还有与rxjava等其他可能用到的类库。

room数据库的使用

设置数据表

room数据库集与实体类和数据表的映射关系,首先看如何创建一个基本的数据表:

@Entity(tableName = "User")
public class User {
    @PrimaryKey((autoGenerate = true))
    @ColumnInfo(name = "id")
    private int id;
    @ColumnInfo(name = "name")
    private String name;
    @ColumnInfo(name = "password")
    private String password;
}

在上面的代码中我们省去了构造函数和获取类变量的方法。可以看到room使用了注解来简化操作,@Entity 注解表示此类为一个数据库的表,同时其中的tableName设置表名,不显示处理表名即为类名。变量注解@Primarykey设置主键和是否自增,@ColumnInfo是必须的,设置变量为数据库的列名。

设置数据库

设置数据库代码如下:其中UserDataDao是我们准备封装的数据库方法。

@Database(entities = {User.class}, version = 1)
public abstract class UserDataBase extends RoomDatabase {
    private static UserDataBase instance;
    public static UserDataBase getInstance(Context context) {
        if (instance == null) {
            instance = Room.databaseBuilder(context.getApplicationContext(), UserDataBase.class,"userdatabase")
                    .allowMainThreadQueries()
                    .addMigrations(MISGRATION_1_2)
                    .fallbackToDestructiveMigration()
                    .build();
        }
        return instance;
    }
    public abstract UserDataDao userDataDao();

注解@Database中的entities关联了数据库表和数据库,后面的version表明数据库的版本,这在数据库的更新中会用到。使用一个静态方法创建数据库,allowMainThreadQueries方法设置可以在主线程中读写数据库,addMigrations是添加数据库升级策略,fallbackToDestructiveMigration允许数据库升级失败后重建而不是直接崩溃。

数据库访问Dao

@Dao
public interface UserDataDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insert(User...users);
    @Update
    void updata(User...users);
    @Delete
    void delete(User...users);
    @Query("Select * from User")
    List<User> selectAll();
}

采用已经设置好的注解,OnConflictStrategy设置冲突时解决策略,即当插入一行时如果此行已经存在即覆盖。room会自动生成一个impl的类,其中实现了具体的SQL执行过程。

使用方式

    userDataBase = UserDataBase.getInstance(this);
    userDataDao=userDataBase.userDataDao();
    User user=new User(1, "11", "111");
    userDataDao.insert(user);
    List<User> userList= userDataDao.selectAll();
    tvMain.setText(userList.toString());

room数据库的升级

数据库的升级是较危险的,很容易造成崩溃,客户端数据库的升级和服务器数据库升级场景也有所不同,设想一个场景,某一app升级版本,新版本中数据库表中字段出现增加,而又不想抛弃原有本机保存的数据。注意版本变化和不同的迁移策略,如1迁移到2 2迁移到3,当前版本如为3可能还需要添加1到3的方法,防止出现错误,下面是几种迁移例子:

    static Migration MISGRATION_1_2=new Migration(1,2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            //迁移范例1 创建新表
              database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, "
                + "`name` TEXT, PRIMARY KEY(`id`))");
                   database.execSQL("ALTER TABLE Book "
                + " ADD COLUMN pub_year INTEGER");

            //迁移范例2 添加字段
                 database.execSQL("ALTER TABLE Book "
                + " ADD COLUMN pub_year INTEGER");

            //迁移范例3 遍历修改字段
            Cursor cursor= database.query("select * from User");
            do {
                while (cursor.moveToNext()) {
                    Log.e("TAG", "migrate: "+cursor.getString(cursor.getColumnIndex("password")) );
                    String sql="insert into User (password) values (?)";
                    SupportSQLiteStatement statement= database.compileStatement(sql);
                    statement.bindString(1, "22222");
                    statement.execute();
                }
            }while (cursor.moveToFirst());
        }
    };

其他

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

gradle此设置可以导出数据库相关信息,包括建表语句查询语句等。

吾生也有涯,而知也無涯。以有涯隨無涯,殆已
原文地址:https://www.cnblogs.com/baimiyishu/p/15506374.html