Room数据库的补充
关于Android官方的Room数据库框架的使用
关于Room
Room是一个对象关系映射(ORM)库。Room抽象了SQLite的使用,可以在充分利用SQLite的同时访问流畅的数据库。
Room由三个重要的组件组成:Database、Entity、DAO
- Database:包含数据库持有者,并作为与应用持久关联数据的底层连接的主要访问点。而且Database对应的类必须满足下面几个条件:
1. 必须是abstract类而且的extends RoomDatabase。- 必须在类头的注释中包含与数据库关联的实体列表(Entity对应的类)。
- 包含一个具有0个参数的抽象方法,并返回用@Dao注解的类。
- 在运行时,你可以通过Room.databaseBuilder() 或者 Room.inMemoryDatabaseBuilder()获取Database实例。
- Entity:代表数据库中某个表的实体类。
- DAO:包含用于访问数据库的方法。
添加依赖
1 | def room_version = "2.2.5" |
使用方法
- 首先创建一个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)表示主键自增
- 接下来就是创建数据库管理类
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的升级过程
- 之后就是创建数据库的操作类
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也是一样,不过这个返回类型是支持背压
- 在Activity/Fragment中使用
- 首先为了防止重复创建数据库,我们创建一个类继承Application
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public 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;
}
} - 在需要的Activity/Fragment中获取数据库实例
1
2
3
4
5
6
7
8
9
10
11public 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来使用
- 首先为了防止重复创建数据库,我们创建一个类继承Application
添加依赖
1 | // RxJava support for Room |
使用RxJava来进行数据库操作
- 增上述操作是往数据库中添加了”一本”书的信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16Completable 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
17Completable 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);
}
}); - 改上述操作是将查询到的数据循环改变BookName的值,在通过数据库操作来更新”全部”数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20for (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);
}
});
} - 查上述操作是将查询到的数据”全部”保存起来
1
2
3
4
5
6
7
8
9
10
11
12db.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());
}
}
});
以上就是全部内容