在工作中难免会遇到使用数据库的需求,现在的数据库框架有好多眼花缭乱各有优势,最后在GreenDao与Room中选择了Google强烈推荐的Room。简单的记录一下使用。
一介绍:
Room持久库提供了一个SQLite抽象层,让你访问数据库更加稳健,提升数据库性能。
该库帮助您在运行应用程序的设备上创建应用程序的数据缓存。这个缓存是你的应用程序唯一的真实来源,允许用户查看应用程序中关键信息的一致副本,而不管用户是否有Internet连接。
二ROOM概念
1概念
1. Entity:一个Entity对应数据库中的一张表。Entity类是Sqlite表结构对Java类的映射,在Java中可以看作一个Model类。
2. Dao:数据访问对象(Data Access Objects),我们通过它来访问数据。
2关系
1. 一个Entity代表一张表,而每张表都需要一个Dao对象,用于对表进行增删改查;
2.Room数据库在被实例化之后我们就可以通过数据库实例获取Dao对象,然后通过Dao进行数据库操作。
三使用
1依赖
参考官方文档:https://developer.android.google.cn/jetpack/androidx/releases/room
def room_version = "2.3.0"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
// optional - RxJava2 support for Room
implementation "androidx.room:room-rxjava2:$room_version"
// optional - RxJava3 support for Room
implementation "androidx.room:room-rxjava3:$room_version"
// optional - Guava support for Room, including Optional and ListenableFuture
implementation "androidx.room:room-guava:$room_version"
// optional - Test helpers
testImplementation "androidx.room:room-testing:$room_version"
2 创建类
@Entity(tableName = "user_info")
public class User {
@PrimaryKey
@NonNull//主键想为除int,Integer的其他类型需标注
public String name;
public int age;
public int phone;
public User() {
}
@Ignore
public User(@NonNull String name, int age, int phone) {
this.name = name;
this.age = age;
this.phone = phone;
}
@NonNull
public String getName() {
return name;
}
public void setName(@NonNull String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getPhone() {
return phone;
}
public void setPhone(int phone) {
this.phone = phone;
}
}
3.创建dao层
结合rxjava异步使用:
1.Completable:只有onComplete和onError方法,即是只有“完成”和“错误”两种状态,不会返回具体的结果。
2.Single:其回调为onSuccess和onError,查询成功会在onSuccess中返回结果,需要注意的是,如果未查询到结果,即查询结果为空,会直接走onError回调,抛出EmptyResultSetException异常。
3.Maybe:其回调为onSuccess,onError,onComplete,查询成功,如果有数据,会先回调onSuccess再回调onComplete,如果没有数据,则会直接回调onComplete。
4.Flowable/Observable:这是返回一个可观察的对象,每当查询语句查询的部分有变化时,都会回调它的onNext方法,直到Rx流断开。
@Dao
public interface UserDao {
//插入数据
@Insert(onConflict = OnConflictStrategy.REPLACE)//重复添加替换
Completable insert(User...users);
//删除数据
@Delete
Completable delete(User... users);
//删除全部数据
@Query("DELETE FROM user_info")
Completable deleteall();
//修改数据
@Update
Completable update(User... users);
//不设置条件,查询所有数据
@Query("SELECt * FROM user_info")
Single<List<User>> queryall();
}
4创建数据库
//@Database绑定数据库表,设置版本号
//room不能在主线程使用 如需测试使用添加.allowMainThreadQueries()
@Database(entities = {User.class},version = 1,exportSchema = false)
public abstract class MyDataBase extends RoomDatabase {
private static final String DATABASE_NAME = "user_db";
private static MyDataBase databaseInstance;
//结合单例模式完成创建数据库实例
public static synchronized MyDataBase getDatabaseInstance() {
if (databaseInstance == null) {
databaseInstance = Room.databaseBuilder(BaseApplication.getConText(), MyDataBase.class, DATABASE_NAME)
// .allowMainThreadQueries()//添加可在主线程使用(建议测试)
.build();
}
return databaseInstance;
}
//将第四步创建的Dao对象以抽象方法的形式返回
public abstract UserDao getUserDao();
}
5.测试
创建三个button,删除与插入同理只演示一种。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".UserActivity">
<Button
android:id="@+id/insert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加" />
<Button
android:id="@+id/Delete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删除" />
<Button
android:id="@+id/SELECt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查询" />
</LinearLayout>
public class UserActivity extends BaseActivity<ActivityUserBinding> {
@Override
protected void initData() {
binding.insert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
User user=new User("张三",12,123456789);
Completable insert = MyDataBase.getDatabaseInstance().getUserDao().insert(user);
insert.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new CompletableObserver() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onComplete() {
Toast.makeText(UserActivity.this, "数据插入成功", Toast.LENGTH_SHORT).show();
Log.d("wch", "数据插入成功");
}
@Override
public void onError(@NonNull Throwable e) {
Log.d("wch", "数据插入失败");
}
});
}
});
binding.Delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
binding.SELECt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Single<List<User>> search = MyDataBase.getDatabaseInstance().getUserDao().queryall();
search.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<User>>() {
@Override
public void accept(List<User> users) throws Exception {
Toast.makeText(UserActivity.this, users.toString(), Toast.LENGTH_SHORT).show();
Log.d("wch", "数据查询成功");
}
});
}
});
}
效果图:
点击添加
点击查询
参考:
https://blog.csdn.net/Ricardo6/article/details/88385613
https://blog.csdn.net/danceinkeyboard/article/details/111938810