Room的使用与遇到的一系列坑的解决方式

之前一直用的greendao这个第三方数据库框架,说实话,觉得greendao用起来是非常智能和简便的,但是,随着17年谷歌io大会中room的横空出世,陆续的开发者们开始对room蠢蠢欲动。说实话,性能真的比greendao好很多。

废话不多说,开始介绍怎么用。

首先官方介绍的Room非常的详细了,想了解更多的同志们,可以去看看。

1.配置

首先在我们app build.gradle中(首先版本号,建议不要直接使用最新的版本,因为可能存在不稳定的情况,最好用之前的1到2个版本较好 我这里用的是 3.0.0-beta01)

dependencies {
    ...
    ...
    def room_version = "2.0.0-beta01"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version" // use kapt for Kotlin
}

好的就这么简单,就ok了,当然如果你的项目用的是 kotlin ,那么配置只需要将 annotationProcessor 换成 kapt 当然 你还要添加kapt的配置,这里不多介绍。当然,配置完了rebuild的时候一定会报错,因为引用了androidx构建替代了android support所以导致了不兼容的问题,ok很简单,将我们需要变成androidx的依赖项转换过来就OK了嘛。首先鼠标选中我们的项目,右键,然后refactor—Migrate to Androidx 然后ok然后选中我们需要转换的项 refactor 就可以喽。解决了androidx与android support冲突问题喽。

2.使用

room总体是由三部分组成也是通过注解的方式进行的操作(bean,dao,database)。

1)bean

@Entity
public class User {
        @PrimaryKey(autoGenerate = true)
        private int uid;
        private String firstName;
        private String lastName;
        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;
        }
}

bean是通过一个Entity这个注解来定义就ok,然后必须要有一个主键,我这里指定的是uid。

2)dao

@Dao
public interface UserDao {
    @Query("SELECT * FROM user")
    List<User> getAllUsers();
    @Insert
    void insert(User user);
    @Update
    void update(User... users);
    @Delete
    void delete(User... users);
}

dao这里我只是简单的介绍了一下,因为room可以用原生的sqlite进行语句的编写,所以,dao里面可以我们灵活的操作。

3)

@Database(entities = {User.class}, version = 1,exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
    public abstract UserDao userDao();
    private static AppDatabase instance;
    public static AppDatabase getInstance(Context context,String DB_PATH){
        synchronized (AppDatabase.class){
            if (instance == null){
                instance = Room.databaseBuilder(context,AppDatabase.class,DB_PATH).build();
            }
            return instance;
        }
    }
}

database这里是创建数据库的操作,因为我们可能要创建多张表,这时需要我们写一个path接口,这样可以灵活的创建多个表哦,而且这里必须要单例因为我们在增删改查的时候,会重复的利用database这个类,所以开销会很大。每次我们的数据库内容改变的时候,数据库版本和表名都会增加,所以这里必须要加exportSchema = false

4)使用

我这里简单的介绍增加一条数据,然后查询展示出来OK。
我这里是将我的db文件放在了sd卡下的指定目录。

    String DB_PATH = Environment.getExternalStorageDirectory().getAbsolutePath()+"/DB_ROOM"+"/datas.db";

如果你也是这么操作,不要忘记添加权限哦

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

如果你是6.0以上的设备,那么需要在清单文件中配置基础上还要动态的设置,我这里写了一个工具类,PermisionUtils 可以供使用。

添加数据

    private void inster() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                User user = new User();
                user.setFirstName("张三");
                user.setLastName("李四");
                //添加数据到数据库中
                AppDatabase.getInstance(getApplicationContext(),DB_PATH).userDao().insert(user);
            }
        }).start();
    }

查询数据&显示

    private void query() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                final List<User> allUsers = AppDatabase.getInstance(getApplicationContext(),DB_PATH).userDao().getAllUsers();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvs.setText(allUsers.get(0).getFirstName()+allUsers.get(0).getLastName());
                    }
                });
            }
        }).start();
    }

(重点)这里说一下,增删改查的操作,必须要在子线程中操作。ok,这样我们就可以灵活的操作喽。

猜你喜欢

转载自blog.csdn.net/mintent/article/details/85770859