软件编程
位置:首页>> 软件编程>> Android编程>> Android Jetpack中Room的使用

Android Jetpack中Room的使用

作者:IT_zhazhanan  发布时间:2021-11-11 08:43:36 

标签:Jetpack,Room,android

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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com