Android 数据库-Room

前言

最近项目中用得数据库框架 “ActivieAndroi” 由于作者停止维护了,它在升级到8.0之后会发生Crash,因此,我们准备给项目换一个数据库。主要考虑了Relam,Room,GreendDao 三个开源得数据库框架。

内容

Room

Google 支持的ARCH框架推荐;使用原生SQL;注解

使用

网上一半教程都是在翻译官方文档,有兴趣的可以自己去看下官方给的Document & Demo

Git:https://github.com/googlesamples/android-architecture-components/
Document:https://developer.android.com/training/data-storage/room/

1 引用Room库

dependencies {
    def room_version = "1.1.0" // or, for latest rc, use "1.1.1-rc1"

    implementation "android.arch.persistence.room:runtime:$room_version"
    annotationProcessor "android.arch.persistence.room:compiler:$room_version"

    // optional - RxJava support for Room
    implementation "android.arch.persistence.room:rxjava2:$room_version"

    // optional - Guava support for Room, including Optional and ListenableFuture
    implementation "android.arch.persistence.room:guava:$room_version"

    // Test helpers
    testImplementation "android.arch.persistence.room:testing:$room_version"
}

2 定义数据表实体类

@Entity(tableName = "user_tb")
public class UserRoom {

    @PrimaryKey(autoGenerate = true)
    private int uid;
    @ColumnInfo
    private String name;
    @ColumnInfo
    private int age;
    @ColumnInfo
    private Date birthday;
    ... 省略了get/set
}

3 编写Dao
直接看Code吧,因为是ORM数据库,注解当然少不了。是不是有点想Retrofit得写法?而且支持写原生SQL,我觉得是很Nice得!别特么说Android程序员不需要学SQL,没点底子出了问题你都不晓得咋搞的。

@Dao
public interface UserDao {

    @Insert
    Long insertUser(UserRoom user);

    @Query("SELECT * FROM user_tb")
    Flowable<List<UserRoom>> queryAll();

    @Query("SELECT * FROM user_tb")
    List<UserRoom> queryForAll();

    @Query("SELECT * FROM user_tb WHERE name = :name")
    int deleteByName(String name);

    @Query("SELECT * FROM user_tb WHERE datetime(birthday/1000, 'unixepoch') >= datetime('now','-1 hour') ")
    Flowable<List<UserRoom>> queryWithinHour();

    @Delete
    void deleteUser(UserRoom user);

    @Query("DELETE FORM user_tb where uid = :id")
    void deleteUserById(int id)

}

4 在NApplication中初始化
写一个类继承RoomDatabaes,我是写了一个单利.

// 要生成的数据表实例类
@Database(entities = {UserRoom.class},version = 1,exportSchema = false)
// 如果要存储Date数据,需要加这个来转换
@TypeConverters({DateConverts.class})
public abstract class AndroidDataBases extends RoomDatabase {

    public abstract UserDao userDao();

    private static volatile AndroidDataBases INSTANCE;

    public static AndroidDataBases crateDatabases(Context context) {
        if (INSTANCE == null) {
            synchronized (AndroidDataBases.class) {
                if (INSTANCE == null) {
                    INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            AndroidDataBases.class, "room.db")
                            .build();
                }
            }
        }
        return INSTANCE;
    }

    public static AndroidDataBases getInstance(){
        return INSTANCE;
    }
}


public class DateConverts {
    @TypeConverter
    public static Date revertDate(Long value) {
        return value == null ? null : new Date(value);
    }

    @TypeConverter
    public static Long converterDate(Date date) {
        return date == null ? null : date.getTime();
    }
}

CURD

有一点需要注意得是Room默认是必须在子线程操作得,否则抛异常。

    // 先获取一个UserDao
    var userDao: UserDao = AndroidDataBases.getInstance().userDao()().userDao();

    // 插入一条数据
    val user: UserRoom = UserRoom("admin2", 25, Date(System.currentTimeMillis()))
            AsyncTask.execute({
                var raw = userDao.insertUser(user)
                Log.d("picher","操作行号:"+raw)
            })
    // 查询数据
    AsyncTask.execute(Runnable {
                 var raws = userDao.queryForAll()
                 Log.d("picher","数据库:"+raws.size)
             })
    // 删除数据 & 修改数据类似 只要在Dao中写好了直接调

看下用了Rx得写法(有坑,插入数据时也会触发这个回掉):

首先需要引用Room 自己的RX库。

// RxJava support for Room
    compile "android.arch.persistence.room:rxjava2:1.1.1-rc1"
 private fun flowableDemo() {
           userDao.queryAll().subscribeOn(Schedulers.io())
                   .map({ users -> 
                       var names = ""
                       for (item in users) names += item.name
                       names
                   }).observeOn(AndroidSchedulers.mainThread()).subscribe({ names -> showTv.text =names})
    }

Room的坑

  1. 实例要给一个空参构造.
  2. 要支持存储Date类型的数据必须加@DateConvert.
  3. 和Rx一起用的时候需要引用Room的Rx库.
  4. Rx在查询完记得dispose,否则每次操作操作数据库都会收到回掉

暂时就遇到这些坑,之后如果遇到再来补上。大家慎踩…

总结

个人感觉上手还是不错的,开发上也比较爽,还能练写原生SQL,有Retrtofit使用经验的上手更快,只是大项目先别急着上,毕竟才出来,先把坑排一排在用。

猜你喜欢

转载自blog.csdn.net/moxiouhao/article/details/80668018