android ORM 框架 search
1. ORMLite
特性:
- 通过在类上添加注解设置类
- 强大抽象DAO类
- QueryBuilder 可以灵活的构造简单和复杂的查询语句
- 支持MySQL, Postgres, Microsoft SQL Server, H2, Derby, HSQLDB, and Sqlite, 并且能够容易的扩展到其它的关系数据库
- 临时支持DB2, Oracle, ODBC and Netezza.
- 能防止编译好的语句重复查询
- 支持外键
- 支持基本的数据库事务
- 自动生成创建和删除SQL语句
- 支持不用注解配置表和字段
2. androidorm
主要功能特征:
1.实现数据库与java对象之间的映射转换
2.增加属性时自动更新数据库结构而不影响数据
3.支持sql直接操作,包括取对象列表
4.基于Apache License 2.0,可任意修改或二次开发
ActiveAndroid
主要功能特征:
1.实现数据库与java对象之间的映射转换
2.增加属性时自动更新数据库结构而不影响数据
3. 支持onetomany
不足:
1. 数据表中一定有一列是id
在项目正式发布进行代码混淆时需要在proguard配置文件中添加以下部分:
-keep class com.activeandroid.** { *; } -dontwarn com.ikoding.app.biz.dataobject.** -keep public class com.ikoding.app.biz.dataobject.** { *;} -keepattributes *Annotation*
具体来说就是com.activeandroid包中的代码不做混淆,标注有@Table注解的类不做混淆,并且不能去掉标注有@Table类的属性上的@Column注解。
性能比较:
硬件环境:模拟器:nexus s(800*480) 内存:512M
插入20000条数据(两个表有关联关系,A表4个字段,B表2个字段)
第一次:
框架类型 | 用时(ms) |
ormlite | 38445 |
activeandroid | 132376 |
第二次:
框架类型 | 用时(ms) |
ormlite | 47384 |
activeandroid | 142627 |
第三次:
框架类型 | 用时(ms) |
ormlite | 41974 |
activeandroid | 133260 |
平均:
框架类型 | 用时(ms) |
ormlite | 42601 |
activeandroid | 136087.7 |
插入速度,activeandroid 明显没有ormlite 效率高, 都是批量插入。
从20000多条数据中查询20条
第一次:
框架类型 | 用时(ms) |
ormlite | 310 |
activeandroid | 195 |
第二次:
框架类型 | 用时(ms) |
ormlite | 86 |
activeandroid | 72 |
第三次:
框架类型 | 用时(ms) |
ormlite | 89 |
activeandroid | 80 |
第四次:
框架类型 | 用时(ms) |
ormlite | 95 |
activeandroid | 53 |
第五次:
框架类型 | 用时(ms) |
ormlite | 89 |
activeandroid | 36 |
第六次:
框架类型 | 用时(ms) |
ormlite | 81 |
activeandroid | 61 |
第七次:
框架类型 | 用时(ms) |
ormlite | 87 |
activeandroid | 51 |
平均:除了第一次之外的平均值
框架类型 | 用时(ms) |
ormlite | 87 |
activeandroid | 58 |
现象:
1. 第一次普遍大,框架类型ormlite在300ms左右;而activeandroid在200ms左右。
可能原因是:
1. 第一次的原因是,在查询是需要与数据库建立连接,需要耗时长
2. 第二次时间短,不用再建立连接。
3. 在一次之后,某次查询时间才,因为数据连接被关闭。需要重新建立连接
4. ormlite 使用完连接,很快会释放, activeandroid 不会很快释放 所有activeandroid的查询速度比ormlite 快
备注 :如果读者有提高ormlite 查询速度的方案,请留言, 谢谢
测试代码:
ormlite:
插入:
getHelper().getDao().callBatchTasks(new Callable<Void>(){
@Override
public Void call() throws Exception {
long t1 = System.currentTimeMillis() ;
for(int i = 3 ; i < 10003 ; i ++){
Classes cl = new Classes() ;
cl.setName("cl" + i) ;
getHelper().getClassesDao().create(cl);
Student student2 = new Student() ;
student2.setName("stu" + i) ;
student2.setAge(i) ;
student2.setClasses(cl) ;
getHelper().getDao().create(student2) ;
}
System.out.println(System.currentTimeMillis() - t1);
return null;
}}) ;
查询:
long t1 = System.currentTimeMillis() ;
QueryBuilder<Student, Integer> builder = getHelper().getDao().queryBuilder() ;
builder.where().le("_id", 50) ;
builder.limit(20l).orderBy("_id", false);
List<Student> stus = getHelper().getDao().query(builder.prepare()) ;
System.out.println(System.currentTimeMillis() - t1);
activeandroid:
插入:
long t1 = System.currentTimeMillis() ;
ActiveAndroid.beginTransaction();
try {
for(int i = 4 ; i < 10004 ; i ++){
Classes cl = new Classes() ;
cl.setName("cl" + i) ;
cl.save();
Student student2 = new Student() ;
student2.setName("stu" + i) ;
student2.setAge(i) ;
student2.setClasses(cl) ;
student2.save();
}
ActiveAndroid.setTransactionSuccessful();
}
finally {
ActiveAndroid.endTransaction();
}
System.out.println(System.currentTimeMillis() - t1);
查询:
long t1 = System.currentTimeMillis() ;
List<Student> students = new Select().from(Student.class).where("id <= ?", 50).limit(20).orderBy("id desc").execute() ;
System.out.println(System.currentTimeMillis() - t1);