Android Jetpack中Room的使用
作者:IT_zhazhanan 发布时间:2021-11-11 08:43:36
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;
}
来源:https://blog.csdn.net/IT_zhazhanan/article/details/120724281


猜你喜欢
- 它所表示的是“这部分是无法修改的”。不想被改变的原因有两个:效率、设计。使用到final的有三种情况:数据、方法、类。一、 final数据有
- Java NIO读取大文件已经不是什么新鲜事了,但根据网上示例写出的代码来处理具体的业务总会出现一些奇怪的Bug。针对这种情况,我总结了一些
- 玩安卓的人都知道adb,玩adb的人都知道install和uninstall,但是为什么adb shell pm install packa
- 废话不多说了,直接给大家贴代码了,具体代码如下所述:package com.example.esp8266;import java.io.I
- PreparedStatement介绍可以通过调用 Connection 对象的 prepareStatement(String sql)
- 前言在开发过程中经常会遇到比较排序的问题,比如说对集合数组的排序等情况,基本类型都提供了默认的比较算法,如string提供了按字母进行排序,
- 1.先通过程序生成报表样式的HTML页面,然后修改HTML页面的后缀名为DOC。 2.定制WORD文档的模板文件,在C#中操作WORD模板,
- 引入依赖 <dependency> <g
- 1.SpringBoot整合JDBCTemplate1.1.导入jdbc相关依赖包主要的依赖包:<dependency> &nb
- 先扯再说最近一直在研究某个国产开源的MySQL数据库中间件,拉下其最新版的代码到eclipse后,启动起来,然后做各种测试和代码追踪;用完想
- 本文实例讲述了C#实现获取鼠标句柄的方法,分享给大家供大家参考。具体实现方法如下:一、调用user32.dll(1)引用using Syst
- java 枚举的功能挺多,但是坑更多,使用的时候要注意。如下面这个枚举。@Getter@AllArgsConstructorpublic e
- 解析XML文件:在Android平台上可以使用SAX、DOM和Android附带的pull解析器解析XML文件;pull解析器提供了各种事件
- 一直在使用Mybatis这个ORM框架,都是使用mybatis里的一些常用功能。今天在项目开发中有个业务是需要限制各个用户对某些表里的字段查
- 在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需要根据用户当前网络情况来做一些调整的,
- 前言记得在介绍 motion_toast 一篇的时候,开篇有一张动图,边框是渐变色而且感觉是流动的。这个动效挺有趣的,当时也有人问怎么实现,
- 项目背景我们开发过程中会碰到这样一类问题,就是数据层或三方接口返回的Bean对象需要转换重新装换一下我们需要的对象。我们通常的做法就是通过g
- 国际化(internationalization)是设计和制造容易适应不同区域要求的产品的一种方式。它要求从产品中抽离所有地域语言,国家/地
- 实践过程效果代码public partial class Form1 : Form{ public Form1()
- 前言在Android开发过程中,不管是写Demo还是实战项目中,都会打印一些日志用于记录数据,调试来着,Android中的日志工具类是Log