Android Room VS GreenDao
数据库比较
本文档对数据库方案GreenDao和Room方案进行对比,用于确定数据库方案的选型。
数据库基本操作
实体类定义
在GreenDao中定义实体类
@Entitypublic class User{ @Id private String username; private String password;}
在Room中定义实体类
@Entitypublic class User { @PrimaryKey @NonNull private String name; private String pwd}@Daopublic interface UserDao { @Insert void insertUsers(User ... users);}@Database(entities = {User.class},version = 1)public abstract class ExternRomDb extends RoomDatabase{ public abstract UserDao userDao();}
定义实体类的都是采用注解的方式,基本形式差不多。
使用Room数据库注意点:
- Room定义实体类需要注意必须手动编写Getter和Setter。
- 同时存在多个构造函数是,只有一个构造函数可以被Room库调用,其他构造函数必须添加注解@Ignore。
- 主键值必须为非空,如果主键设置为String等,需要添加注解@NonNull
- 实体类要生效必须注解在Database中。
- Dao对象需要开发者编写各entity对应的Dao接口或者抽象类,并用@Dao注解标注,接口中提供需要的方法声明。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);}@Daopublic 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; }}
- 小结:
- GreenDao和Room 在定义实体类和获取Dao 来操作数据库方面,总体差不多,不能判断其优劣。
- GreenDao 和Room 在基本操作方面,Room提供的接口比较少,对SQL命令的依赖度高,有点是可以在编译的时候检查SQL命令,但是在项目中有多个实体类的时候,会出现很多重复性代码。GreenDao提供的接口丰富,支持SQL操作,但是无法检测SQL命令,通过泛型话操作,可以减少重复性代码。
数据库高级操作
完整的查询语句为:
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 提供的操作接口有:
- 与SQL order by相关的接口,QueryBuilder.orderxx()
- 与SQL limit 相关的接口,QueryBuilder.limit()
- 与SQL offset相关的接口,QueryBuilder.offset()
- 未提供group by ,having 相关接口,因此使用这两个关键字,必须使用原生查询。
- 小结
在高级操作方面,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数据库框架。
更多相关文章
- Android调用相机接口
- 全球支持最多运行平台的NoSQL数据库 iBoxDB
- Android Bitmap 缩放 旋转 水印 裁剪操作
- Android Sqlite Failed to open database(无法打开数据库文件)
- Android联系人数据库全解析(4)
- Android联系人数据库全解析(3)
- Android数据库操作查询中Cursor类的问题
- 在SQLite数据库中获取新插入数据自增长的ID值(传智播客笔记)