特性
避免了样板间似的代码块。
能轻松的将SQLite表数据转换为Java对象
Room提供了编译SQLite语句时检查,避免了SQL语句在执行时,才发现错误
可以返回RxJava的Flowable和LiveData的可观察实例,对SQLite的异步操作提供强力支持。
Room的三大组成部分
Database(数据库):使用此组件创建数据库Holder。
通过注解实体类定义表结构,该实体类的实例即为数据库中的数据访问对象(在Dao内操作)。
它是链接SQL底层的主要接入点。
注解的类必须是继承于RoomDatabase的抽象类
在运行时,可以通过调用Room.databaseBuilder()或Room.inMemoryDatabaseBuilder()获取其实例
Entity(实体类):该组件表示持有一个表的字段(即数据库一行的数据)的实体类。
对于每个实体,创建一个数据库表来保存它们。
必须通过Database类中的Entity数组引用实体类
实体类的每个字段都会保存数据库的表中。如果不想保存某字段,该字段需使用@Ignore注解
DAO(抽象类/接口):该组件表示作为数据访问对象(DAO即为Data Access Object的简写)的类或者接口。
DAO是Room的主要组件,负责定义访问数据库的方法。
该抽象类或接口使用@Database注解,同时必须含有一个无参数的抽象方法,并返回@Dao注解的实际操作类。
在编译时,Room创建这个抽象类或接口的实现。
插入数据,一些注解说明
OnConflictStrategy.REPLACE:冲突策略是取代旧数据同时继续事务
OnConflictStrategy.ROLLBACK:冲突策略是回滚事务
OnConflictStrategy.ABORT:冲突策略是终止事务
OnConflictStrategy.FAIL:冲突策略是事务失败
OnConflictStrategy.IGNORE:冲突策略是忽略冲突
AppDataBase类
package com.example.banbeichas.roomdemo;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.RoomDatabase;
@Database(entities ={User.class},version = 1)
public abstract class AppDataBase extends RoomDatabase {
abstract UserDao userdao();
}
User类
package com.example.banbeichas.roomdemo;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.Ignore;
import android.arch.persistence.room.PrimaryKey;
@Entity(tableName = "Table_User")//表名字
public class User {
@PrimaryKey(autoGenerate = true) //设置自增长,默认是false,必须要设置主键,不然会报错
private int id;
private String userName;
//字段映射具体的数据表字段名
@ColumnInfo(name = "uid")
private int uid;
private String firstName;
private String lastName;
public User() {
}
@Ignore
public User(int uid, String userName) {
this.uid = uid;
this.userName = userName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
UserDao类
package com.example.banbeichas.roomdemo;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.OnConflictStrategy;
import android.arch.persistence.room.Query;
import android.arch.persistence.room.Update;
import java.util.List;
import io.reactivex.Flowable;
@Dao
public interface UserDao {
//简单sql语句,查询user表所有的column
@Query("SELECT * FROM table_user")
Flowable<List<User>> getAll();
//根据条件查询,方法参数和注解的sql语句参数一一对应
@Query("SELECT * FROM table_user WHERE uid IN (:userIds)")
List<User> loadAllByIds(int[] userIds);
//同上
@Query("SELECT * FROM table_user WHERE firstName LIKE :first AND "
+ "lastName LIKE :last LIMIT 1")
User findByName(String first, String last);
//同上
@Query("SELECT * FROM table_user WHERE uid = :uid")
User findByUid(int uid);
//-----------------------insert----------------------
// OnConflictStrategy.REPLACE表示如果已经有数据,那么就覆盖掉
//数据的判断通过主键进行匹配,也就是uid,非整个user对象
//返回Long数据表示,插入条目的主键值(uid)
@Insert(onConflict = OnConflictStrategy.REPLACE)
Long insert(User user);
//返回List<Long>数据表示被插入数据的主键uid列表
@Insert(onConflict = OnConflictStrategy.REPLACE)
List<Long> insertAll(User... users);
//返回List<Long>数据表示被插入数据的主键uid列表
@Insert(onConflict = OnConflictStrategy.REPLACE)
List<Long> insertAll(List<User> users);
//---------------------update------------------------
//更新已有数据,根据主键(uid)匹配,而非整个user对象
//返回类型int代表更新的条目数目,而非主键uid的值。
//表示更新了多少条目
@Update()
int update(User user);
//同上
@Update()
int updateAll(User... user);
//同上
@Update()
int updateAll(List<User> user);
//-------------------delete-------------------
//删除user数据,数据的匹配通过主键uid实现。
//返回int数据表示删除了多少条。非主键uid值。
@Delete
int delete(User user);
//同上
@Delete
int deleteAll(List<User> users);
//同上
@Delete
int deleteAll(User... users);
}
使用
package com.example.banbeichas.roomdemo;
import android.arch.persistence.room.Room;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.util.List;
import io.reactivex.functions.Consumer;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button btn_insert, btn_search, btn_delete, btn_alert;
private UserDao userDao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_insert = findViewById(R.id.btn_insert);
btn_search = findViewById(R.id.btn_search);
btn_delete = findViewById(R.id.btn_delete);
btn_alert = findViewById(R.id.btn_alert);
btn_insert.setOnClickListener(this);
btn_search.setOnClickListener(this);
btn_delete.setOnClickListener(this);
btn_alert.setOnClickListener(this);
AppDataBase appDataBase = Room.databaseBuilder(this, AppDataBase.class, "appData")
//.allowMainThreadQueries()在主线程操作
.build();
userDao = appDataBase.userdao();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_insert:
new Thread() {
@Override
public void run() {
Long i = userDao.insert(new User(214325, "哈哈哈哈"));
Log.i("run: ", i + "");
}
}.start();
break;
case R.id.btn_search:
userDao.getAll().subscribe(new Consumer<List<User>>() {
@Override
public void accept(List<User> users) throws Exception {
Log.i("accept: ", users.size() + "");
}
});
break;
case R.id.btn_delete:
new Thread() {
@Override
public void run() {
User user = new User();
user.setId(1);
int i = userDao.delete(user);
Log.i("run: ", i + "");
}
}.start();
break;
case R.id.btn_alert:
new Thread() {
@Override
public void run() {
User user = new User();
user.setId(2);
user.setFirstName("如题哈哈哈");
int i = userDao.update(user);
Log.i("run: ", i + "");
}
}.start();
break;
}
}
}