Room在SQLite之上提供了一个抽象层来访问数据库,可以在充分利用SQLite强大功能的同时对数据库进行流畅的访问。

优点

  • 减少了写大量代码来在SQL查询和Java数据对象之间进行转换。
  • 数据层改变自动更新SQL查询。减少了查询过程的耗时。

使用

添加依赖

compile "android.arch.persistence.room:runtime:1.0.0-beta1"annotationProcessor "android.arch.persistence.room:compiler:1.0.0-beta1"

可能发生的错误

Error:Failed to resolve: android.arch.persistence.room:runtime:1.0.0-beta1Error:Failed to resolve: annotationProcessor

解决办法:
往工程级别下的gradle文件里添加google的maven仓库

allprojects {    repositories {        jcenter()        maven {            url 'https://maven.google.com'        }    }}

Room三要素:

  • Dao:用来处理数据库操作,如增删改查,编译的时候会生成_impl结尾的实现类,实现在DAO中定义的增删改查方法
  • Entity:实体类,一个实体类对应一张表
  • Database:作为底层连接数据库的主要接入点,它是一个抽象的类,并继承RoomDatabase,编译的时候会自动生成一个_impl结尾的实现类,实现数据库以及表的创建及打开

代码:

Tips:这里使用了RxJava2.0里的Completable以及Maybe用来处理数据库操作,以及ui更新。
为什么用Maybe不用Single?Maybe是发送0个或1个数据,而single是发送一个数据并且结果要么成功要么错误抛异常。

创建一个DAO接口,这个接口主要是提供数据库增删改查方法,编译的时候会生成一个BookDao_Impl的实现类:
BookDao.java

@Daopublic interface BookDao {    //这里使用Maybe    @Query("SELECT * FROM book")    Maybe> getAllBooks();    @Query("SELECT * FROM book where bookid = :id")    Maybe getBookById(int id);    @Insert    void insertAll(Book... books);    @Delete    void delete(Book book);    @Update    void updateBooks(Book... books);}

Entity: 一个实体类对应一张表
Book.java

@Entity(tableName = "book")public class Book {    @PrimaryKey(autoGenerate = true)    private int bookid;    @ColumnInfo(name = "book_name")    private String bookName;    @ColumnInfo(name = "author")    private String author;    public void setAuthor(String author) {        this.author = author;    }    public String getAuthor() {        return author;    }    public void setBookid(int bookid) {        this.bookid = bookid;    }    public int getBookid() {        return bookid;    }    public void setBookName(String bookName) {        this.bookName = bookName;    }    public String getBookName() {        return bookName;    }}

Database:抽象类,编译的时候会生成一个BookDatabase_Impl实现类,实现数据库和表的创建打开,并且实现bookDao()方法
BookDatabase.java

@Database(entities = {Book.class}, version = 1)public abstract class BookDatabase extends RoomDatabase {    public abstract BookDao bookDao();}

DatabaseCallback.java 用于更新ui和提示操作结果

public interface DatabaseCallback {    void onLoadBooks(List books);    void onAdded();    void onDeleted();    void onUpdated();    void onError(String err);}

创建一个Manager方便我们对数据库进行管理操作:
注意:数据库的操作要在子线程中进行,不要在主线程进行操作
LocalCacheManager.java

public class LocalCacheManager {    private static LocalCacheManager _instance;    private BookDatabase db;    private static final String DB_NAME = "book-database";    public static LocalCacheManager getInstance(Context context) {        if (_instance == null) {            _instance = new LocalCacheManager(context);        }        return _instance;    }    public LocalCacheManager(Context context) {        db = Room.databaseBuilder(context, BookDatabase.class, DB_NAME).build();    }    public void getBooks(final DatabaseCallback databaseCallback) {        db.bookDao()                .getAllBooks()                //在io线程进行数据库操作                .subscribeOn(Schedulers.io())                //在主线程进行数据反馈                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Consumer>() {                    @Override                    public void accept(@NonNull List books) throws Exception {                        databaseCallback.onLoadBooks(books);                    }                });    }    public void addBook(final DatabaseCallback databaseCallback, final Book... books) {        //这里使用Completable是因为数据库处理完后不发射数据,只处理onComplete 和 onError 事件        Completable                .fromAction(new Action() {                    @Override                    public void run() throws Exception {                        db.bookDao().insertAll(books);                    }                })                //在主线程进行反馈                .observeOn(AndroidSchedulers.mainThread())                //在io线程进行数据库操作                .subscribeOn(Schedulers.io())                .subscribe(new CompletableObserver() {                    @Override                    public void onSubscribe(Disposable d) {                    }                    @Override                    public void onComplete() {                        databaseCallback.onAdded();                    }                    @Override                    public void onError(Throwable e) {                        databaseCallback.onError(e.getMessage());                    }                });    }    public void delete(final DatabaseCallback databaseCallback, final int id) {        Completable                .fromAction(new Action() {                    @Override                    public void run() throws Exception {                        Book book = new Book();                        book.setBookid(id);                        db.bookDao().delete(book);                    }                })                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new CompletableObserver() {                    @Override                    public void onSubscribe(Disposable d) {                    }                    @Override                    public void onComplete() {                        databaseCallback.onDeleted();                    }                    @Override                    public void onError(Throwable e) {                        databaseCallback.onError(e.getMessage());                    }                });    }    public void getBookById(final DatabaseCallback callback, int id) {        db.bookDao().getBookById(id).observeOn(AndroidSchedulers.mainThread())                .subscribeOn(Schedulers.io())                .subscribe(new Consumer() {                    @Override                    public void accept(@NonNull Book book) throws Exception {                        ArrayList list = new ArrayList<>();                        list.add(book);                        callback.onLoadBooks(list);                    }                });    }    public void updateBook(final DatabaseCallback callback, final Book... book) {        Completable.fromAction(new Action() {            @Override            public void run() throws Exception {                db.bookDao().updateBooks(book);            }        }).subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new CompletableObserver() {                    @Override                    public void onSubscribe(Disposable d) {                    }                    @Override                    public void onComplete() {                        callback.onUpdated();                    }                    @Override                    public void onError(Throwable e) {                        callback.onError(e.getMessage());                    }                });    }}

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener, DatabaseCallback {    TextView panel;    Button btnAdd, btnDelete, btnSelect,btnUpdate;    EditText etName, etId, etAuthor;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btnAdd = findViewById(R.id.add);        btnDelete = findViewById(R.id.delete);        btnSelect = findViewById(R.id.select);        etName = findViewById(R.id.name);        etId = findViewById(R.id.id);        etAuthor = findViewById(R.id.author);        panel = findViewById(R.id.panel);        btnUpdate = findViewById(R.id.update);        btnAdd.setOnClickListener(this);        btnDelete.setOnClickListener(this);        btnSelect.setOnClickListener(this);        btnUpdate.setOnClickListener(this);    }    @Override    public void onClick(View view) {        switch (view.getId()) {            case R.id.add:                if (etName.getText().toString().trim().length() > 0 && etAuthor.getText().toString().trim().length() > 0 && etId.getText().toString().trim().length() > 0) {                    final Book book = new Book();                    book.setAuthor(etAuthor.getText().toString().trim());                    book.setBookName(etName.getText().toString().trim());                    LocalCacheManager.getInstance(getApplicationContext()).addBook(MainActivity.this, book);                } else {                    Toast.makeText(this, "Please input", Toast.LENGTH_SHORT).show();                }                break;            case R.id.delete:                if (etId.length() > 0) {                    LocalCacheManager.getInstance(getApplicationContext()).delete(MainActivity.this, Integer.parseInt(etId.getText().toString().trim()));                }                break;            case R.id.select:                if (etId.length() > 0) {                    LocalCacheManager.getInstance(getApplicationContext()).getBookById(MainActivity.this, Integer.parseInt(etId.getText().toString().trim()));                } else {                    LocalCacheManager.getInstance(getApplicationContext()).getBooks(MainActivity.this);                }                break;            case R.id.update:                if (etId.length() > 0) {                    final Book book = new Book();                    book.setBookid(Integer.parseInt(etId.getText().toString().trim()));                    book.setAuthor(etAuthor.getText().toString().trim());                    book.setBookName(etName.getText().toString().trim());                    LocalCacheManager.getInstance(getApplicationContext()).updateBook(MainActivity.this, book);                }                break;        }    }    @Override    public void onLoadBooks(List books) {        panel.setText("");        for (Book book : books) {            panel.append("\nID:" + book.getBookid() + "\nName:" + book.getBookName() + "\nAuthor:" + book.getAuthor());        }    }    @Override    public void onAdded() {        Toast.makeText(this, "Add Successfully", Toast.LENGTH_SHORT).show();    }    @Override    public void onDeleted() {        Toast.makeText(this, "Deleted Successfully", Toast.LENGTH_SHORT).show();    }    @Override    public void onUpdated() {        Toast.makeText(this, "Updated Successfully", Toast.LENGTH_SHORT).show();    }    @Override    public void onError(String err) {        Toast.makeText(this, err, Toast.LENGTH_SHORT).show();    }}

运行发现警告错误:

Error: 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 module下的gradle文件里添加下面代码:

android {    ...    defaultConfig {        ...        javaCompileOptions {            annotationProcessorOptions {                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]            }        }    }    ...}

最后

相比Sqlite,Room上手非常简单,因为有关数据库以及表的创建,还有增删改查的实现,都在编译的时候自动帮你写好了,我们只需要关心在哪个线程调用哪个方法进行处理,不需要关心具体实现。但是还是建议新手有时间可以看看_Impl结尾的类里面是怎么实现的。

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. GreenDao 3.3.0 增删改查的使用(三)
  3. Android(安卓)registerContentObserver 接口监视数据库变化
  4. 安卓数据库连接解决办法 ,避免 sqlite3 database is locked
  5. 学习ContentProvider---之一:查询数据库
  6. RxJava(九)zip 操作符在 Android(安卓)中的实际使用场景
  7. Android(安卓)Bluetooth 蓝牙基本操作
  8. 梳理Android的IPC进程间通信(最新AndroidStudio的AIDL操作)
  9. 10、Android数据存储

随机推荐

  1. Android View绘制机制
  2. android:gallery相册
  3. android开机启动代码
  4. Vuforia How To Use Android Plugins in
  5. Android打开本地文件
  6. Android中获取正在运行的服务-------Acti
  7. android两列显示两个listview
  8. Android中Gallery来显示图片
  9. Android图片按比例缩放
  10. 基于Android的sina微博分享功能