本文档对数据库方案GreenDao和Room方案进行对比,用于确定数据库方案的选型。
在GreenDao中定义实体类
@Entity
public class User{
@Id
private String username;
private String password;
}
在Room中定义实体类
@Entity
public class User {
@PrimaryKey
@NonNull
private String name;
private String pwd
}
@Dao
public interface UserDao {
@Insert
void insertUsers(User ... users);
}
@Database(entities = {User.class},version = 1)
public abstract class ExternRomDb extends RoomDatabase{
public abstract UserDao userDao();
}
定义实体类的都是采用注解的方式,基本形式差不多。
使用Room数据库注意点:
使用GreenDao,使用GreenDao时会自动生成DaoMaster,DaoSession,XXXEntityDao三个类。
DaoSession daoSession = new DaoMaster(db).newSession();
UserDao dao = daoSession.getUserDao();
Room提供的注解方法有
@Insert,@Delete,@Update,@Query, @RawQuery 等等
基于Room基本操作的封装优化,减少不必要的重复代码。与query相关的接口,必须通过SQL命令来实现。可以将入参作为SQL的一部分。
public interface BaseDao<T> {
@Insert
void insert(T ... obj);
@Delete
void delete(T ... obj);
@Update
void update(T ... obj);
}
@Dao
public abstract class UsrDao implements BaseDao<User>{
@Query("select * from User")
abstract List<User> loadAll();
@Query("select * from User where User.name =:name")
People queryById(Stirng name);
}
GreenDao在AbstractDao提供的基本操作有
public T load(K key) ; public List<T> loadAll(),public long insert(T entity) 等等
总体来说GreenDao提供的操作接口更为丰富。基于可以通过泛型对象优化。
public interface IDatabase<M, K>{
boolean insert(M m);
boolean delete(M m);
boolean deleteByKey(K key);
...
}
public abstract class AbstractDatabaseManager<M, K> implements IDatabase<M, K>{
@Override
public boolean insert(M m) {
openWritableDb();
getAbstractDao().insert(m);
return true;
}
public boolean delete(M m){
openWritableDb();
getAbstractDao().delete(m);
return true;
}
}
完整的查询语句为:
select [distinct] heading from tables where predicate group by columns having predicate order by columns limit count , offset;
Room数据库实现高级操作有两种方式
方式1,在接口或者抽象类中,通过注解Query来实现。
优点:AS 字段SQL语法检查,可以对列名,表名,关键字进行语法检查。
缺点:入参只能作为值传入到SQL中,不能出入列名。
@Query("select * from User where User.pwd >:pwd order by User.name")
List<People> queryWhere(String pwd);
方法2:通过@RawQuery来实现。
优点:自定化程度高。
缺点:这是方式是命令拼接,无法进行SQL语法检查。
@RawQuery
List<Cheese> queryRaw(SupportSQLiteQuery query);
void test(String pwd,String orderBy){
String cmd = "select * from User where User.pwd > "+pwd+" order by " +orderBy;
queryRaw(new SimpleSQLiteQuery(cmd));
}
GreenDao 提供的操作接口有:
在高级操作方面,GreenDao 胜在接口丰富,且提供查询缓存,提供了效率,但是查询缓存使用不当,也容易出现问题。Room胜在提供了SQL语法检查,但是由于列名作为语法检查项,因此不能作为入参传入,在某些情况下面,会出现接口性代码非常多。
Room和GreenDao 本身都不支持数据库加密,必须引入第三方库进行数据加密。两个框架操作类似。
Room数据库升级,由于Room 编译生成的表名和列名,没有存放在任何实例中,因此只能通过SQL指令对数据库进行升级
static final Migration MIGRATION_1_2 = new Migration(1, 2)
{
@Override
public void migrate(@NonNull SupportSQLiteDatabase database)
{
//执行升级相关操作
}
};
Room.databaseBuilder(context.getApplicationContext(), MyDatabase.class, DATABASE_NAME)
.addMigrations(MIGRATION_1_2)
.build();
由于Schema是描述Room生成数据库表的结构,因此可以通过Schema查看,数据库升级是否满足要求。
GreenDao数据库升级,由于GreenDao编译生成的表名和列名,存在在实例中DaoConfig
中,因此可以创建一个统一升级方式。统计升级方式参见MigrationHelper.java
小结:
从数据库升级方面来说,GreenDao的方面性,远大于Room。
Room支持RxJava,LiveData两个方式的响应式编程。
GreenDao支持Rxjava
Room 作为Jetpack的组件之一,与Jetpack的其他组件如LiveData,paging有着密切的关系。
Room数据库的框架与GreenDao框架相比较,Room和GreenDao各有胜场。在目前看来,可以根据项目自身情况选择数据库框架,已使用GreenDao数据框架的项目,没有足够的理由切换为Room数据库框架。