一诀黍、前言
Room是一個(gè)持久層庫(kù)仗处,它可以使我們更加方便的操作SQLite數(shù)據(jù)庫(kù)。下面我們介紹它的具體使用婆誓。
二、Room的使用介紹
1模叙、創(chuàng)建User實(shí)體
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;
/**
* 實(shí)體類
*/
@Entity(tableName = "user")
public class UserDto {
//主鍵 自增長(zhǎng)
@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內(nèi)嵌到 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 + '\'' +
'}';
}
}
下面介紹實(shí)體中的注解含義:
@Entity(tableName = "user") 指數(shù)據(jù)表名為 user
@PrimaryKey(autoGenerate = true) 設(shè)置主鍵鞋屈,autoGenerate = true 指主鍵自增長(zhǎng)
@ColumnInfo(name = "sex") 列名
@Ignore 需要忽略的字段或方法
@Embedded 把其他實(shí)體嵌入到該實(shí)體故觅,也就是說渠啊,該數(shù)據(jù)表將擁有其他數(shù)據(jù)表的屬性
2、創(chuàng)建操作數(shù)據(jù)庫(kù)的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;
/**
* 操作數(shù)據(jù)庫(kù)的dao層 接口
*/
@Dao
public interface UserDao {
/**
* 查詢用戶列表
* @return
*/
@Query("select * from user")
List<UserDto> findUserList();
/**
* 添加用戶
* @param userDtos 可變參數(shù) 可以多個(gè)
*/
@Insert
void addUser(UserDto...userDtos);
/**
* 根據(jù)ID查詢用戶
* @param ids 可以多個(gè)ID 查詢多個(gè)用戶
*/
@Query("select * from user where id in (:ids)")
List<UserDto> findUserById(Long[] ids);
/**
* 更加用戶名查詢
* @param username
* @return
*/
@Query("select * from user where username = (:username)")
List<UserDto> findUserByName(String username);
/**
* 刪除用戶
* @param userDtos
*/
@Delete
void deleteUser(UserDto...userDtos);
/**
* 更新用戶
* @param userDtos
*/
@Update
void updateUser(UserDto...userDtos);
/**
* 結(jié)合 LiveData使用
* @return
*/
@Query("select * from user")
LiveData<List<UserDto>> findUserListForLiveData();
/**
* 結(jié)合RxJava使用
* @return
*/
@Query("select * from user")
Flowable<List<UserDto>> findUserListFoRxJava();
}
在DAO層我們定義了常規(guī)的增刪改查的方法贯溅,同時(shí)我們可以配合LiveData和RxJava一起使用躲查。
3它浅、初始化數(shù)據(jù)庫(kù)
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;
/**
* 創(chuàng)建數(shù)據(jù)庫(kù)
*/
@Database(entities = {UserDto.class,UserInfo.class},version = 1)
public abstract class AppDataBase extends RoomDatabase {
private static AppDataBase appDataBase;
//對(duì)外提供需要操作數(shù)據(jù)庫(kù)的DAO
public abstract UserDao getUserDao();
/**
* 以單實(shí)例的形式初始化數(shù)據(jù) 并對(duì)外提供 AppDataBase實(shí)例
* @param context
* @return
*/
public static AppDataBase getInstance(Context context){
if(appDataBase==null){
synchronized (AppDataBase.class){
if(appDataBase==null){
//"user" 為數(shù)據(jù)庫(kù)名
appDataBase = Room.databaseBuilder(context.getApplicationContext(),AppDataBase.class,"user_data").build();
}
}
}
return appDataBase;
}
}
初始化數(shù)據(jù)庫(kù)需要?jiǎng)?chuàng)建抽象類并繼承RoomDatabase姐霍,我們使用Database 注解典唇,并指定相應(yīng)的實(shí)體創(chuàng)建數(shù)據(jù)表镊折,和數(shù)據(jù)庫(kù)版本 version介衔。并在抽象類中創(chuàng)建獲取DAO的方法 。
//對(duì)外提供需要操作數(shù)據(jù)庫(kù)的DAO
public abstract UserDao getUserDao();
然后我們通過單實(shí)例的方式初始化數(shù)據(jù)庫(kù)赃泡,并對(duì)外提供RoomDatabase實(shí)例。
/**
* 以單實(shí)例的形式初始化數(shù)據(jù) 并對(duì)外提供 AppDataBase實(shí)例
* @param context
* @return
*/
public static AppDataBase getInstance(Context context){
if(appDataBase==null){
synchronized (AppDataBase.class){
if(appDataBase==null){
//"user" 為數(shù)據(jù)庫(kù)名
appDataBase = Room.databaseBuilder(context.getApplicationContext(),AppDataBase.class,"user_data").build();
}
}
}
return appDataBase;
}
我們通過RoomDatabase實(shí)例可以拿到DAO對(duì)象急迂,接著通過DAO對(duì)象即可對(duì)數(shù)據(jù)表進(jìn)行操作蹦肴。
下面我們通過例子來介紹:
三弯洗、實(shí)例
創(chuàng)建RoomActivity咖气,分別對(duì)數(shù)據(jù)庫(kù)進(jìn)行增刪改查的操作
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<UserDto> 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<UserDto> 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<List<UserDto>> userListForLiveData = AppDataBase.getInstance(RoomActivity.this).getUserDao().findUserListForLiveData();
userListForLiveData.observe(RoomActivity.this, new Observer<List<UserDto>>() {
@Override
public void onChanged(@Nullable List<UserDto> 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<UserDto>> list = AppDataBase.getInstance(RoomActivity.this).getUserDao().findUserListFoRxJava();
//IO 線程獲取數(shù)據(jù)
list.subscribeOn(Schedulers.io())
//線程切換
.observeOn(AndroidSchedulers.mainThread()).
subscribe(new Subscriber<List<UserDto>>() {
@Override
public void onSubscribe(Subscription s) {
// 觀察者接收事件 = 1個(gè)
s.request(1);
}
@Override
public void onNext(List<UserDto> 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() {
}
});
}
});
}
}
四雪标、注意
需要注意的是议忽,對(duì)SQLite的操作是一個(gè)耗時(shí)的操作十减,我們需要在子線程中執(zhí)行栈幸,否則將會(huì)拋異常。