一、前言
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层 接口 */@Daopublic interface UserDao { /** * 查询用户列表 * @return */ @Query("select * from user") List<UserDto> findUserList(); /** * 添加用户 * @param userDtos 可变参数 可以多个 */ @Insert void addUser(UserDto...userDtos); /** * 根据ID查询用户 * @param ids 可以多个ID 查询多个用户 */ @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); /** * 结合 LiveData使用 * @return */ @Query("select * from user") LiveData<List<UserDto>> findUserListForLiveData(); /** * 结合RxJava使用 * @return */ @Query("select * from user") Flowable<List<UserDto>> 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<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 线程获取数据 list.subscribeOn(Schedulers.io()) //线程切换 .observeOn(AndroidSchedulers.mainThread()). subscribe(new Subscriber<List<UserDto>>() { @Override public void onSubscribe(Subscription s) { // 观察者接收事件 = 1个 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() { } }); } }); } }
四、注意
需要注意的是,对SQLite的操作是一个耗时的操作,我们需要在子线程中执行,否则将会抛异常。
作者:大熊啊啊啊
链接:https://www.jianshu.com/p/eac17c60be86