Android Jetpack中Room的使用

Room

Room主要分三个部分 database、dao和实体类entity

Entity

entity实体类定义时需要用到@Entity(tableName = "student")注解,其中参数为表名

主键定义需要用到@PrimaryKey(autoGenerate = true)注解,参数决定是否自增长

每个属性(也就是表的字段)都需要加@ColumnInfo(name = "name",typeAffinity = ColumnInfo.TEXT)注解 ,name是表中的字段名、 typeAffinity是字段类型,类型有:

// 未定义类型关联。将基于类型进行解析。
int UNDEFINED = 1;
​
// 文本类型
int TEXT = 2;
​
// 整数或布尔值的列关联常数。
int INTEGER = 3;
​
// 用于浮点数或双精度数的列关联常数。
int REAL = 4;
​
// 二进制数据的列亲和常数。
int BLOB = 5;

实体类需要指定一个构造方法。如果我们有多个构造方法,那么就需要告诉room忽略其他的构造器,不然会报错,room只可以使用一个构造器。构造函数上加入@Ignore注解即可(想忽略一个属性也是)

@Entity(tableName = "student")
public class Student {
​
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id",typeAffinity = ColumnInfo.INTEGER)
    public int id;
​
    @ColumnInfo(name = "name",typeAffinity = ColumnInfo.TEXT)
    public String name;
​
    @ColumnInfo(name = "age",typeAffinity = ColumnInfo.INTEGER)
    public int age;
​
    @ColumnInfo(name = "sex",typeAffinity = ColumnInfo.INTEGER)
    public int sex;
    @Ignore// 告诉room忽略这个构造方法
    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
​
    @Ignore// 告诉room忽略这个构造方法
    public Student(int id) {
        this.id = id;
    }
    // 指定room用的构造方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Dao

dao是一个interface,需要加入一个@Dao注解,内部主要声明一些对数据做操作的抽象方法,方法都需要加上room中特定的注解

@Insert 添加

@Update 修改

@Delete 删除

@Query 查询 此注解需要加入参数 参数就是sql语句

@Dao
public interface StudentDao {
    @Insert
    void  insertStudent(Student...students);
​
    @Query("SELECT * FROM student")
    List<Student> getAllStudent();
​
    @Query("SELECT * FROM student WHERE id=:id")
    List<Student> getAllStudentById(int id);
​
    @Query("DELETE FROM student")
    void clearAll();
​
    @Update
    void upData(Student...students);

    @Delete
    void delete(Student...students);
}

DataBase

database类需要继承RoomDatabase这个抽象类,dataBase也必须是抽象类。需要加入@DataBase注解

@Database(entities =
{Student.class}, version = 1, exportSchema = false)  // entities-实体类  version-数据库版本 exportSchema-是否生成schema文件,schema文件中包含的是表结构和信息

如果想生成schema文件 还需要在build.gradle中指定schema文件的生成位置

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"
​
    defaultConfig {
        applicationId "com.example.room"
        minSdkVersion 20
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
​
        //指定room.schemaLocation生成的文件路径
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }
}

database类需要是单例的 但是不需要写私有构造器,继承了RoomDatabase之后room会识别,只需要一个getInstance方法,内部是database的实例化。

public static synchronized StudentDataBase getInstance(Context context) {
    if (mInstance == null) {
        mInstance = Room.databaseBuilder(context.getApplicationContext(),
                StudentDataBase.class,
                DATABASE_NAME)
                // .allowMainThreadQueries()// 允许在主线程操作数据库
                .addMigrations(MIGRATION_1_2)// 数据库升级时
                .fallbackToDestructiveMigration()// 数据库版本异常时 会清空原来的数据  然后转到目前版本
              //  .createFromAsset("资源文件中的初始数据库")// 预填充数据库  初始数据
                .build();
    }
    return mInstance;
}

还需要声明一个获取dao的抽象方法,只声明即可。

public abstract StudentDao getStudentDao();

当数据库的版本有升级时,就需要使用到Migration,创建Migration(),参数为哪个版本到哪个版本的升级。重写mingrate方法,在mingrate方法内通过database.execSQL()方法来写表的变化(结构变化等)。Migration可以有多个,对应表的多次升级。

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE student ADD COLUMN sex INTEGER NOT NULL DEFAULT 1");// 添加表字段
    }
};

database全貌

@Database(entities = {Student.class}, version = 1, exportSchema = true)
public abstract class StudentDataBase extends RoomDatabase {
    private static StudentDataBase mInstance;
    private static final String DATABASE_NAME = "student.db";
​
    public static synchronized StudentDataBase getInstance(Context context) {
        if (mInstance == null) {
            mInstance = Room.databaseBuilder(context.getApplicationContext(),
                    StudentDataBase.class,
                    DATABASE_NAME)
                    // .allowMainThreadQueries()// 允许在主线程操作数据库
                    .addMigrations(MIGRATION_1_2)// 数据库升级时
                    .fallbackToDestructiveMigration()// 数据库版本异常时 会清空原来的数据  然后转到目前版本
                  //  .createFromAsset("资源文件中的初始数据库")// 预填充数据库  初始数据
                    .build();
        }
        return mInstance;
    }
​
    static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            database.execSQL("ALTER TABLE student ADD COLUMN sex INTEGER NOT NULL DEFAULT 1");// 添加表字段
        }
    };
​
    public abstract StudentDao getStudentDao();
}

使用

获取dao

StudentDataBase dataBase = StudentDataBase.getInstance(this);
StudentDao studentDao = dataBase.getStudentDao();

通过dao操作表,注意对数据库的操作需要放到子线程中操作

class GetAllStudentTask extends AsyncTask<Void,Void,List<Student>>{
    @Override
    protected List<Student> doInBackground(Void... voids) {
        List<Student> allStudent = studentDao.getAllStudent();
        for (int j = 0; j < allStudent.size(); j++) {
            Log.i("student", "doInBackground: "+allStudent.get(j).name+"--id:"+allStudent.get(j).id);
        }
        return allStudent;
    }

到此这篇关于Jetpack中Room的使用的文章就介绍到这了,更多相关Jetpack中Room使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JetPack开发中使用CameraX完成拍照和拍视频功能

    前段时间CameraX的Beta版发布了,这几天有时间也来尝试一下.Beta版本是对外测试版本,意味着它已经走出实验室走向生产,API的调用基本稳定不会大改了,bug也会更少可以用于生成环境. 之前使用Camera1和Camera2开发相机功能的时候需要调用非常复杂的API,而且由于Android手机的碎片化严重,不同手机对相机功能的支持度也不一样,因此很多做相机相关应用的公司都会封装自己的相机库来简化相机的使用步骤和处理兼容性问题. CameraX其实就是Google开发的一个用来简化相机开发

  • 详解Android JetPack之LiveData的工作原理

    前言 本篇文章主要讲解LiveData工作的原理,如果还不知道LiveData如何用的话,请参考官方文档. LiveData的讲解涉及到了Lifecycle的知识,如果你还不了解LifeCycle,请参考文档LifeCycle介绍. 介绍 LiveData是一个数据持有类,它可以通过添加观察者被其他组件观察其变更.不同于普通的观察者,它最重要的特性就是遵从应用程序的生命周期,如在Activity中如果数据更新了但Activity已经是destroy状态,LivaeData就不会通知Activit

  • Android Jetpack架构组件Lifecycle详解

    前言 Lifecycle是Jetpack架构组件中用来感知生命周期的组件,使用Lifecycles可以帮助我们写出和生命周期相关更简洁更易维护的代码. 生命周期 生命周期这个简单而又重要的知识相信大家早已耳熟能详.假设我们现在有这样一个简单需求: 这个需求只是一个实例,在真实的开发中当然不可能有这样的需要: 在Activity 可见的时候,我们去做一个计数功能,每隔一秒 将计数加1 ,当Activity不可见的时候停止计数,当Activity被销毁的时候 将计数置为0 OK,So easy~ ,

  • Android Jetpack- Paging的使用详解

    Google 推出 Jetpack 组件化已经有相当一段时间了.各种组件也层出不穷. Jetpack 的东西也不少, 今天就搞一下这个  Paging Paging 的出现,就是用作列表的分页加载.其实现在已经有非常多成熟高效的开源列表加载控件了,比如:Smartrefreshlayout等.但Google推出的,必然有它的有点,当然也有它的局限性. 先说优点吧,Paging 的使用,需要配合ViewModle,LiveData等控件,数据的请求感知并绑定页面的生命周期,避免了内存泄漏.还需要绑

  • Android Jetpack架构组件 ViewModel详解

    前言 前面两篇文章我们已经学习了Lifecycle和DataBind,本篇文章我们来学习Jetpack系列中比较重要的ViewModel,Jetpack的很多很多组件都是搭配使用的,所以单独的知识点可能会有些"无意义"但却是我们项目实战的基础! ViewModel的使用 ViewModel类旨在以注重生命周期的方式存储和管理界面相关的数据.ViewModel类让数据可在发生屏幕旋转等配置更改后继续存在.这句话很好理解,还记得我们在讲解Lifecycle的时候 举的例子吗,我们还是使用那

  • Android Jetpack中Room的使用

    Room Room主要分三个部分 database.dao和实体类entity Entity entity实体类定义时需要用到@Entity(tableName = "student")注解,其中参数为表名 主键定义需要用到@PrimaryKey(autoGenerate = true)注解,参数决定是否自增长 每个属性(也就是表的字段)都需要加@ColumnInfo(name = "name",typeAffinity = ColumnInfo.TEXT)注解 ,

  • Android Jetpack架构中ViewModel接口暴露的不合理探究

    目录 暴露 Mutable 状态 暴露 Suspend 方法 在 Jetpack 架构规范中, ViewModel 与 View 之间应该遵循单向数据流的通信方式,Events 永远从 View 流向 VM ,而 State 从 VM 流向 View. 如果 ViewModel 对 View 暴露了不适当的接口类型,则会破坏单向数据流的形成.不适当的接口类型常见于以下两点: 暴露 Mutable 状态 暴露 Suspend 方法 暴露 Mutable 状态 ViewModel 对外暴露的数据状态

  • Android Jetpack组件中LifeCycle作用详细介绍

    目录 Jetpack 1.那么Jetpack是什么呢 2.为何使用Jetpack 3.Jetpack与AndroidX LifeCycle 1.LifeCycle的作用 2.LifeCycle应用 1.设计组件 2.使用组件 3.总结LifeCycle的使用 Jetpack Jetpack,我觉得翻译为“飞行器”更好听,因为Google针对编程历史乱象,整理出一套组件库,帮助开发者创造更完美的应用作品.现在市面上,很多公司招聘面试要求渐渐把Jetpack看作必会技能,Google也在疯狂的安利J

  • Android Jetpack Compose无限加载列表

    目录 前言 方法一: paging-compose 方法二:自定义实现 添加 LoadingIndicator 总结 前言 Android 中使用 ListView 或者 RecycleView 经常有滚动到底部自动 LoadMore 的需求,那么在 Compose 中该如何实现呢? 两种方法可供选择: 基于 paging-compose 自定义实现 方法一: paging-compose Jetpack 的 Paging 组件提供了对 Compose 的支持 dependencies { ..

  • Android Jetpack Compose实现列表吸顶效果

    目录 stickyHeader 实体类 加载假数据 吸顶标题 二级条目 完整代码 效果图 安卓传统的 Recyclerview 打造悬浮头部StickyHeader的吸顶效果,十分麻烦,而在Compose中就简单多了 stickyHeader Compose设计的时候考虑得很周到,他们提供了stickyHeader 作用就是添加一个粘性标题项,即使在它后面滚动时也会保持固定.标头将保持固定,直到下一个标头取而代之. 参数key - 表示唯一的密钥键. 它不允许对列表出现使用相同的键.密钥的类型应

  • Android Jetpack组件Navigation导航组件的基本使用

    目录 1.Navigation 基本概念 2.Navigation 使用入门 2.1 添加Navigation依赖 2.2 创建导航图 2.3 导航图中添加目的地Fragment 2.4 Activity添加 NavHost 2.5 LoginFragment 代码编写 2.6 welcomeFragment 代码编写 总结 本篇主要介绍一下 Android Jetpack 组件 Navigation 导航组件的 基本使用 当看到 Navigation单词的时候 应该就大概知道 这是一个关于导航

  • Android Jetpack库剖析之ViewModel组件篇

    前言 今天让我们一起去探究一下ViewModel的实现原理,描述的不对或不足还请海涵,仅作为参考 ViewModel简介 ViewModel是一个可感知Activity或Fragment生命周期的一个架构组件,当视图销毁,数据也会被清除,所以它的本质就是用来存储与视图相关的数据,让视图显示控制与数据分离,即使界面配置发生改变数据也不会被销毁,通常配合LiveData使用 ViewModel用法 class MainActivity : AppCompatActivity() { override

随机推荐