Room数据库的使用

Room数据库的补充

关于Android官方的Room数据库框架的使用

关于Room

Room是一个对象关系映射(ORM)库。Room抽象了SQLite的使用,可以在充分利用SQLite的同时访问流畅的数据库。
Room由三个重要的组件组成:Database、Entity、DAO

  • Database:包含数据库持有者,并作为与应用持久关联数据的底层连接的主要访问点。而且Database对应的类必须满足下面几个条件:
     1. 必须是abstract类而且的extends RoomDatabase。
    1. 必须在类头的注释中包含与数据库关联的实体列表(Entity对应的类)。
    2. 包含一个具有0个参数的抽象方法,并返回用@Dao注解的类。
    3. 在运行时,你可以通过Room.databaseBuilder() 或者 Room.inMemoryDatabaseBuilder()获取Database实例。
  • Entity:代表数据库中某个表的实体类。
  • DAO:包含用于访问数据库的方法。
添加依赖
1
2
3
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
使用方法
  1. 首先创建一个Bean类,用来做为数据库的表
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    @Entity(indices = {@Index("BookName")})
    public class BookBean {

    public BookBean(){ }

    public BookBean(String name,String autohor,Data data){
    this.BookName = name;
    this.BookAuthor = autohor;
    this.data = data;
    }

    @PrimaryKey(autoGenerate = true)
    private int BookId;

    private String BookName;
    private String BookAuthor;
    private static Data data;

    public int getBookId() {
    return BookId;
    }

    public void setBookId(int bookId) {
    BookId = bookId;
    }

    public String getBookName() {
    return BookName;
    }

    public void setBookName(String bookName) {
    BookName = bookName;
    }

    public String getBookAuthor() {
    return BookAuthor;
    }

    public void setBookAuthor(String bookAuthor) {
    BookAuthor = bookAuthor;
    }

    public static class Data{
    private String userName;
    private int userId;

    public String getUserName() {
    return userName;
    }

    public void setUserName(String userName) {
    this.userName = userName;
    }

    public int getUserId() {
    return userId;
    }

    public void setUserId(int userId) {
    this.userId = userId;
    }
    }
    }
    • @Entityd的注释代表数据库中某个表的实体类。默认情况下Room会把Entity里面所有的字段对应到表上的每一列。如果需要制定某个字段不作为表中的一列需要添加@Ignore注解。
    • @Index(“BookName”)代表设置数据库中的索引
    • @PrimaryKey的注释代表数据库中的主键
    • @PrimaryKey的(autoGenerate = true)表示主键自增
  2. 接下来就是创建数据库管理类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Database(entities = {BookBean.class}, version = 1)
    public abstract class AppDatabase extends RoomDatabase {
    public abstract BookDao userDao();

    static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
    database.execSQL("ALTER TABLE bookBean ADD COLUMN index_name'BookName' ");
    }
    };
    }
    • @Database表示当前类为数据库管理类
    • entities = {BookBean.class}表示数据库相关的所有Entity实体类,他们会转化成数据库里面的表。
    • version = 1表示当前数据库的版本(每当数据库更新时,版本号也要对应增加)
    • public abstract BookDao userDao() 这个则是对应数据库的操作类
    • static final Migration MIGRATION_1_2 = new Migration(1, 2) 这个是指当数据库升级时,从版本1升级到版本2的升级过程
  3. 之后就是创建数据库的操作类
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    @Dao
    public interface BookDao {

    @Query("SELECT * FROM bookbean")
    Flowable<List<BookBean>> getAll();

    @Query("SELECT * FROM bookbean WHERE BookId IN (:userIds)")
    List<BookBean> loadAllByIds(int[] userIds);

    @Query("update bookbean set bookauthor = :value")
    void setBookAuthor(boolean value);

    @Insert
    Completable insertAll(BookBean... users);

    @Delete
    Completable delete(BookBean user);

    @Update
    Completable updateUsers(BookBean... users);
    }
    • @Dao 表示这个组件代表了作为DAO的类或者接口。DAO是Room的主要组件,负责定义访问数据库的方法。Room使用过程中一般使用抽象DAO类来定义数据库的CRUD操作。DAO可以是一个接口也可以是一个抽象类。如果它是一个抽象类,它可以有一个构造函数,它将RoomDatabase作为其唯一参数。Room在编译时创建每个DAO实。
    • @Query对应数据库的查询,后接查询语句
    • @Insert对应数据库的插入
    • @Delete对应数据库的删除
    • @Update对应数据库的更新,每次更新都会将没有涉及到的值进行重置
    • Completable返回值是为了和RxJava一起使用,如果不使用RxJava则写成void或者对应类型
    • Flowable也是一样,不过这个返回类型是支持背压
  4. 在Activity/Fragment中使用
    1. 首先为了防止重复创建数据库,我们创建一个类继承Application
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      public class MyApplication extends Application {
      private static AppDatabase db;

      @Override
      public void onCreate() {
      super.onCreate();
      db = Room.databaseBuilder(getApplicationContext(),
      AppDatabase.class, "database-name")
      //.addMigrations(MIGRATION_1_2)
      .build();
      //.allowMainThreadQueries()//允许在主线程中查询
      }

      public static AppDatabase getDatabase(){
      return db;
      }
      }
    2. 在需要的Activity/Fragment中获取数据库实例
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      public class MainActivity extends AppCompatActivity {
      private ActivityMainBinding binding;
      private AppDatabase db;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
      db = MyApplication.getDatabase();
      }

      RxJava+Room
      一般来说对数据库进行操作是不运行在主线程中执行的,因为当进行大量数据库操作时,可能会堵塞主线程,所以可以配合RxJava来使用
添加依赖
1
2
3
4
5
// RxJava support for Room
implementation "androidx.room:room-rxjava2:2.2.5"

implementation 'io.reactivex.rxjava2:rxjava:2.0.6'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
使用RxJava来进行数据库操作
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Completable completable = db.userDao().insertAll(new BookBean("HTML(" + i + ")", "jjj", data));
    completable.subscribeOn(Schedulers.io())
    .subscribe(new CompletableObserver() {
    @Override
    public void onSubscribe(Disposable d) {}

    @Override
    public void onComplete() {
    Log.e("why", "onClick: 插入成功");
    }

    @Override
    public void onError(Throwable e) {
    Log.e("why", "onClick: 插入失败" + e);
    }
    });
    上述操作是往数据库中添加了”一本”书的信息
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Completable comparable = db.userDao().delete(bean);
    comparable.subscribeOn(Schedulers.io())
    .subscribe(new CompletableObserver() {
    @Override
    public void onSubscribe(Disposable d) {
    }

    @Override
    public void onComplete() {
    Log.e("why", "onClick: 删除数据成功");
    }

    @Override
    public void onError(Throwable e) {
    Log.e("why", "onClick: 删除数据失败" + e);
    }
    });
    上述操作是往数据库中删除了”全部”书的信息
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    for (BookBean bean : bookBean) {
    bean.setBookName("JAVA");
    Completable completable = db.userDao().updateUsers(bean);
    completable.subscribeOn(Schedulers.io())
    .subscribe(new CompletableObserver() {
    @Override
    public void onSubscribe(Disposable d) {
    }

    @Override
    public void onComplete() {
    Log.e("why", "onClick: 更新数据成功");
    }

    @Override
    public void onError(Throwable e) {
    Log.e("why", "onClick: 更新数据失败" + e);
    }
    });
    }
    上述操作是将查询到的数据循环改变BookName的值,在通过数据库操作来更新”全部”数据
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    db.userDao().getAll()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Consumer<List<BookBean>>() {
    @Override
    public void accept(List<BookBean> bookBeans) throws Exception {
    bookBean = bookBeans;
    for (BookBean bean : bookBeans) {
    Log.e("why", "onClick: 查询成功,数据为" + bean.toString());
    }
    }
    });
    上述操作是将查询到的数据”全部”保存起来

以上就是全部内容