20180502_从零开始的android持久库room其一
Room是android的一个持久化库,SQLite的抽象层,便于使用。推荐用Room替代SQLite。
20180502_从零开始的android持久库room其一
引入room库Room的3大组件数据访问(增删查改)
InsertDeleteSelectUpdate 注意事项源码地址参考文章
引入room库
在project的gradle中加入google仓库
allprojects {
repositories {
jcenter()
google()
}
}
在app的gradle中加入room依赖
其中最后3个是用来支持rxjava2的,方便使用
dependencies {
// Room (
use 1.1.
0-beta3
for latest beta)
implementation
"android.arch.persistence.room:runtime:1.0.0"
annotationProcessor
"android.arch.persistence.room:compiler:1.0.0"
// RxJava support
for Room (
use 1.1.
0-beta3
for latest beta)
implementation
"android.arch.persistence.room:rxjava2:1.0.0"
implementation
'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation
"io.reactivex.rxjava2:rxjava:2.1.13"
}
初始化
在Application中初始化数据库,记得在AndroidManifest.xml中配置App
public class App extends Application {
private static App instance;
private static AppDatabase db;
@Override
public void onCreate() {
super.onCreate();
instance =
this;
initDb();
}
private void initDb() {
db = Room.databaseBuilder(
this,
AppDatabase.class,
"database-name").build();
}
public static App
getInstance() {
return instance;
}
public static AppDatabase
getDb() {
return db;
}
}
Room的3大组件
Database 数据库Entity 实体类DAO 数据访问对象
概念不是很难,直接看代码更加方便
@Database(entities = {Student.class}, version =
1)
public abstract class AppDatabase extends RoomDatabase {
public abstract StudentDAO
studentDao();
}
@Entity
public class Student {
@PrimaryKey(autoGenerate =
true)
private long uid;
@ColumnInfo(name =
"first_name")
private String firstName;
@ColumnInfo(name =
"last_name")
private String lastName;
private int age;
}
@Dao
public interface StudentDAO {
@Query(
"SELECT * FROM student")
Single<List<Student>> getAll();
@Query(
"SELECT * FROM student WHERE uid IN (:ids)")
Single<List<Student>> loadAllByIds(
int[] ids);
@Query(
"SELECT * FROM student WHERE uid = :id")
Single<Student> findById(
int id);
@Query(
"SELECT * FROM student WHERE first_name LIKE :first AND "
+
"last_name LIKE :last LIMIT 1")
Maybe<Student> findByName(String first, String last);
@Insert
List<Long> insertAll(Student... students);
@Update
void update(Student student);
@Delete
void delete(Student student);
}
数据访问(增删查改)
Insert
Student s =
new Student();
s.setFirstName(firstName);
s.setLastName(lastName);
s.setAge(ageInt);
Callable<List<Long>> callable = () -> App.getDb().studentDao().insertAll(s);
Single.fromCallable(callable)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
new SingleObserver<List<Long>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(List<Long> longs) {
Log.i(TAG, String.format(
"onSuccess: insert success ids = %s", Arrays.toString(longs.toArray())));
Snackbar.make(et_first_name,
"add student success", Snackbar.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Log.e(TAG,
"onError: insert error", e);
Snackbar.make(et_first_name,
"add student fail", Snackbar.LENGTH_SHORT).show();
}
});
Delete
final Student s = studentList.get(position);
Action action = () -> App.getDb().studentDao().delete(s);
Completable.fromAction(action)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
new CompletableObserver() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onComplete() {
Log.i(TAG, String.format(
"onComplete: delete student success id = %d", s.getUid()));
Snackbar.make(rv_list,
"delete student success", Snackbar.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Log.e(TAG,
"onError: delete student fail", e);
Snackbar.make(rv_list,
"delete student fail", Snackbar.LENGTH_SHORT).show();
}
});
}
});
Select
App.getDb().studentDao().getAll()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
new SingleObserver<List<Student>>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onSuccess(List<Student> students) {
Log.i(TAG, String.format(
"onSuccess: students.size = %d", students.size()));
studentList.addAll(students);
adapter.notifyDataSetChanged();
}
@Override
public void onError(Throwable e) {
Log.e(TAG,
"onError: get all student error", e);
Snackbar.make(rv_list,
"select student fail", Snackbar.LENGTH_SHORT).show();
}
});
Update
Action action = () -> {
Student s =
new Student();
s.setUid(idInt);
if (!TextUtils.isEmpty(firstName)) {
s.setFirstName(firstName);
}
if (!TextUtils.isEmpty(lastName)) {
s.setLastName(lastName);
}
if (!TextUtils.isEmpty(age)) {
s.setAge(ageInt);
}
App.getDb().studentDao().update(s);
};
Completable.fromAction(action)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
new CompletableObserver() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onComplete() {
Log.i(TAG,
"onComplete: update student success");
Snackbar.make(et_id,
"update student success", Snackbar.LENGTH_SHORT).show();
}
@Override
public void onError(Throwable e) {
Log.e(TAG,
"onError: update student fail", e);
Snackbar.make(et_id,
"update student fail", Snackbar.LENGTH_SHORT).show();
}
});
到这里,我们已经可以简单的增删查改数据库了。
注意事项
遇到下面的这个警告,说的是找不到地方导出schema
警告: Schema export
directory is
not provided
to the annotation processor so we cannot export
the schema. You can either provide `room.schemaLocation` annotation processor argument OR
set exportSchema
to false.
解决方案
在app的gradle文件中添加
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments = [
"room.schemaLocation":
"$projectDir/schemas".toString()]
}
}
}
}
源码地址
AndroidRoomStudy
参考文章
android room