一、前言
Room是一个持久层库,它可以使我们更加方便的操作SQLite数据库。下面我们介绍它的具体使用。
二、Room的使用介绍
1、创建User实体
package com.jilian.androidarchitecture.common;
import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Embedded;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.Ignore;
import android.arch.persistence.room.PrimaryKey;
/**
* 实体类
*/
@Entity(tableName = "user")
public class UserDto {
//主键 自增长
@PrimaryKey(autoGenerate = true)
//表名
@ColumnInfo(name = "id")
private Long id;
@ColumnInfo(name = "sex")
private String sex;
@ColumnInfo(name = "username")
private String username;
@ColumnInfo(name = "password")
private String password;
// 指示 Room 需要忽略的字段或方法
@Ignore
private String age;
//把 info内嵌到 UserDto中
@Embedded
private UserInfo info;
public UserInfo getInfo() {
return info;
}
public void setInfo(UserInfo info) {
this.info = info;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "UserDto{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
下面介绍实体中的注解含义:
@Entity(tableName = "user") 指数据表名为 user
@PrimaryKey(autoGenerate = true) 设置主键,autoGenerate = true 指主键自增长
@ColumnInfo(name = "sex") 列名
@Ignore 需要忽略的字段或方法
@Embedded 把其他实体嵌入到该实体,也就是说,该数据表将拥有其他数据表的属性
2、创建操作数据库的DAO
package com.jilian.androidarchitecture.dao;
import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;
import android.arch.persistence.room.Update;
import com.jilian.androidarchitecture.common.UserDto;
import java.util.List;
import io.reactivex.Flowable;
/**
* 操作数据库的dao层 接口
*/
@Dao
public interface UserDao {
/**
* 查询用户列表
* @return
*/
@Query("select * from user")
List findUserList();
/**
* 添加用户
* @param userDtos 可变参数 可以多个
*/
@Insert
void addUser(UserDto...userDtos);
/**
* 根据ID查询用户
* @param ids 可以多个ID 查询多个用户
*/
@Query("select * from user where id in (:ids)")
List findUserById(Long[] ids);
/**
* 更加用户名查询
* @param username
* @return
*/
@Query("select * from user where username = (:username)")
List findUserByName(String username);
/**
* 删除用户
* @param userDtos
*/
@Delete
void deleteUser(UserDto...userDtos);
/**
* 更新用户
* @param userDtos
*/
@Update
void updateUser(UserDto...userDtos);
/**
* 结合 LiveData使用
* @return
*/
@Query("select * from user")
LiveData> findUserListForLiveData();
/**
* 结合RxJava使用
* @return
*/
@Query("select * from user")
Flowable> findUserListFoRxJava();
}
在DAO层我们定义了常规的增删改查的方法,同时我们可以配合LiveData和RxJava一起使用。
3、初始化数据库
package com.jilian.androidarchitecture.db;
import android.arch.persistence.room.Database;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.content.Context;
import com.jilian.androidarchitecture.common.UserDto;
import com.jilian.androidarchitecture.common.UserInfo;
import com.jilian.androidarchitecture.dao.UserDao;
/**
* 创建数据库
*/
@Database(entities = {UserDto.class,UserInfo.class},version = 1)
public abstract class AppDataBase extends RoomDatabase {
private static AppDataBase appDataBase;
//对外提供需要操作数据库的DAO
public abstract UserDao getUserDao();
/**
* 以单实例的形式初始化数据 并对外提供 AppDataBase实例
* @param context
* @return
*/
public static AppDataBase getInstance(Context context){
if(appDataBase==null){
synchronized (AppDataBase.class){
if(appDataBase==null){
//"user" 为数据库名
appDataBase = Room.databaseBuilder(context.getApplicationContext(),AppDataBase.class,"user_data").build();
}
}
}
return appDataBase;
}
}
初始化数据库需要创建抽象类并继承RoomDatabase,我们使用Database 注解,并指定相应的实体创建数据表,和数据库版本 version。并在抽象类中创建获取DAO的方法 。
//对外提供需要操作数据库的DAO
public abstract UserDao getUserDao();
然后我们通过单实例的方式初始化数据库,并对外提供RoomDatabase实例。
/**
* 以单实例的形式初始化数据 并对外提供 AppDataBase实例
* @param context
* @return
*/
public static AppDataBase getInstance(Context context){
if(appDataBase==null){
synchronized (AppDataBase.class){
if(appDataBase==null){
//"user" 为数据库名
appDataBase = Room.databaseBuilder(context.getApplicationContext(),AppDataBase.class,"user_data").build();
}
}
}
return appDataBase;
}
我们通过RoomDatabase实例可以拿到DAO对象,接着通过DAO对象即可对数据表进行操作。
下面我们通过例子来介绍:
三、实例
创建RoomActivity,分别对数据库进行增删改查的操作
package com.jilian.androidarchitecture;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.Observer;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.jilian.androidarchitecture.common.UserDto;
import com.jilian.androidarchitecture.db.AppDataBase;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import java.util.List;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
public class RoomActivity extends AppCompatActivity {
private static final String TAG = "RoomActivity";
private TextView add;
private TextView update;
private TextView delete;
private TextView query;
private TextView queryList;
private TextView queryLiveData;
private TextView queryRxJava;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_room);
add = (TextView) findViewById(R.id.add);
update = (TextView) findViewById(R.id.update);
delete = (TextView) findViewById(R.id.delete);
query = (TextView) findViewById(R.id.query);
queryList = (TextView) findViewById(R.id.queryList);
queryLiveData = (TextView) findViewById(R.id.queryLiveData);
queryRxJava = (TextView) findViewById(R.id.queryRxJava);
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread() {
@Override
public void run() {
super.run();
UserDto userDto = new UserDto();
userDto.setUsername("daxiaa");
userDto.setPassword("123456");
AppDataBase.getInstance(RoomActivity.this).getUserDao().addUser(userDto);
}
}.start();
}
});
update.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread() {
@Override
public void run() {
super.run();
UserDto userDto = new UserDto();
userDto.setUsername("zaizai");
userDto.setId(1l);
userDto.setPassword("111111");
AppDataBase.getInstance(RoomActivity.this).getUserDao().updateUser(userDto);
}
}.start();
}
});
delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread() {
@Override
public void run() {
super.run();
UserDto userDto = new UserDto();
userDto.setId(1l);
AppDataBase.getInstance(RoomActivity.this).getUserDao().deleteUser(userDto);
}
}.start();
}
});
query.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread() {
@Override
public void run() {
super.run();
List list = AppDataBase.getInstance(RoomActivity.this).getUserDao().findUserByName("zaizai");
for (int i = 0; i < list.size(); i++) {
Log.e(TAG, "user:" + list.get(i).toString());
;
}
}
}.start();
}
});
queryList.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread() {
@Override
public void run() {
super.run();
List list = AppDataBase.getInstance(RoomActivity.this).getUserDao().findUserList();
for (int i = 0; i < list.size(); i++) {
Log.e(TAG, "user:" + list.get(i).toString());
;
}
}
}.start();
}
});
queryLiveData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread() {
@Override
public void run() {
super.run();
LiveData> userListForLiveData = AppDataBase.getInstance(RoomActivity.this).getUserDao().findUserListForLiveData();
userListForLiveData.observe(RoomActivity.this, new Observer>() {
@Override
public void onChanged(@Nullable List list) {
if (list != null) {
for (int i = 0; i < list.size(); i++) {
Log.e(TAG, "user:" + list.get(i).toString());
}
}
}
});
}
}.start();
}
});
queryRxJava.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Flowable> list = AppDataBase.getInstance(RoomActivity.this).getUserDao().findUserListFoRxJava();
//IO 线程获取数据
list.subscribeOn(Schedulers.io())
//线程切换
.observeOn(AndroidSchedulers.mainThread()).
subscribe(new Subscriber>() {
@Override
public void onSubscribe(Subscription s) {
// 观察者接收事件 = 1个
s.request(1);
}
@Override
public void onNext(List list) {
for (int i = 0; i < list.size(); i++) {
Log.e(TAG, "user:" + list.get(i).toString());
}
}
@Override
public void onError(Throwable t) {
}
@Override
public void onComplete() {
}
});
}
});
}
}
四、注意
需要注意的是,对SQLite的操作是一个耗时的操作,我们需要在子线程中执行,否则将会抛异常。