GreenDao、Ormlite、Realm性能对比

来源:互联网 发布:二叉树的结点算法 编辑:程序博客网 时间:2024/06/03 14:47

GreenDao、Ormlite、Realm性能对比

       该博文为我本人亲测,代码编写过程中使用到了百度上很多大神的demo,如http://blog.csdn.net/shareye1992/article/details/50789216,http://blog.csdn.net/hedong_77/article/details/53167774,http://blog.csdn.net/wds1181977/article/details/51584052等博文。自己学习的同时也希望大家一起成长,第一次写自己的,博客希望大家能够谅解

       当前android开发中常用的数据库框架有GreenDao、Ormlite、Realm等,这里本人仅就自己的对这三种数据库框架增、删、改、查四个方面运行速度上的性能进行对比,并附上相关代码。下面就这三个框架逐个分析。

一、  GreenDao

1.在 ANDROID 工程中配置「GREENDAO GENERATOR」模块

GreenDAO是一个将对象映射到 SQLite 数据库中的轻量且快速ORM 解决方案。这里我所进行测试的GreenDao版本为greendao:1.3.7。详细测试demo流程如下:

(1)新建工程,并在src/main/java文件下新建package包javagen(这里不同于网上所说在java同级目录下建立java-gen)。

(2)配置 Android 工程(app)的 build.gradle,添加

sourceSets {

    main {

        java.srcDirs = ['src/main/java','src/main/java/javagen']

    }

}

compile'de.greenrobot:greendao:1.3.7'


如图所示:



2.新建纯 JAVA 工程「GREENDAO GENERATOR」模块

(1)通过 File -> New -> New Module -> JavaLibrary -> 填写相应的包名与类名 -> Finish.此处本人包名为daoexamplegenerator类名为ExampleDaoGenerator,完成后编写ExampleDaoGenerator类代码,具体如下:

public class ExampleDaoGenerator {
    public static void main(String[] args) throws Exception {
     //两个参数分别代表:数据库版本号与自动生成代码的包路径。
        Schema schema = new Schema(1, "lzy.greendao");
        addNote(schema);
        // 最后我们将使用 DAOGenerator 类的 generateAll() 方法自动生成代码,此处你需要根据自己的情况更改输出目录。        
  New DaoGenerator().generateAll(schema,"/software_forwork/androidstudio/MyProject/
                                         DaoDemo/app/src/main/java/javagen");    
}    
    private static void addNote(Schema schema) {
  // 一个实体(类)就关联到数据库中的一张表,此处表名为「Note」(既类名)
        Entity note = schema.addEntity("Note");      
        note.addIdProperty();
        note.addStringProperty("text").notNull();    
        note.addStringProperty("comment");        
    }
}

3.自动生成文件

执行 generator 工程,如一切正常,你将会在控制台看到如下日志,并且在主工程「java-gen」下会发现生成了DaoMaster、DaoSession、NoteDao、Note共4个类文件。此时文件结构如下图:


4.在MainActivity中进行测试,具体代码如下:

 

public class MainActivityextends AppCompatActivity {
   
private SQLiteDatabasedb;
   
private DaoMaster daoMaster;
   
private DaoSession daoSession;
   
private Cursor cursor;
   
public static final String TAG= "DaoExample";
   
@Override
 
  protectedvoid onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
       
setContentView(R.layout.activity_main);
       
setupDatabase();
       
new Thread(newRunnable() {
           
@Override
           
public void run() {
               
deletetAll();
               
//addNote();
              
// search();
            }
       
}
        ).start();
   
}

private void setupDatabase() {
   
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this,"notes-db", null);
   
db = helper.getWritableDatabase();
   
// 注意:该数据库连接属于 DaoMaster,所以多个 Session指的是相同的数据库连接。
   
daoMaster =new DaoMaster(db);
   
daoSession =daoMaster.newSession();
}

 

private void search() {    // Query 类代表了一个可以被重复执行的查询    Long before=Long.valueOf(System.currentTimeMillis());    System.out.println("查询之前的时间为:"+before);    List<Note> list= getNoteDao().loadAll();    System.out.println(list.get(9999).getText()+"***************************************");    Long after=Long.valueOf(System.currentTimeMillis());    System.out.println("查询之后的时间为:"+after);    System.out.println("时间差为"+(after-before)+"毫秒");}
public void deletetAll() {
   
Long before=Long.valueOf(System.currentTimeMillis());
   
System.out.println("删除之前的时间为:"+before);
   
getNoteDao().deleteAll();
   
Long after=Long.valueOf(System.currentTimeMillis());
   
System.out.println("删除之后的时间为:"+after);
   
System.out.println("时间差为"+(after-before)+"毫秒");

}

private void addNote()     String noteText = "小明";    String comment = "Added on ";    // 插入操作,简单到只要你创建一个 Java 对象    Note note =null;    Long before=Long.valueOf(System.currentTimeMillis());    System.out.println("存储之前的时间为:"+before)for(int i=0;i<10000;i++){      note=new Note(null,noteText+i,comment);      getNoteDao().insert(note);      note=null;   }    Long after=Long.valueOf(System.currentTimeMillis());    System.out.println("存储之后的时间为:"+after);    System.out.println("时间差为"+(after-before)+"毫秒");}

 



 

4.效果对比

由上述代码在线程中依次调用增、查、删,效果如下图(分别对10000条数据、1000条数据进行增、查、删):

 

 

二、  Ormlite

ORMLite是对象关系映射(Object Relational Mapping)数据库的一种轻量级SQL数据库的开发包(packages)。提供简单易用的DAO。首先需要下载相关jar包,本测试用的一个是ormlite-core-4.24.jar,另一个是ormlite-android-4.24.jar。

1.创建Bean

将下载好的jar包导入工程,并完成Bean的编写,此处bean与GreenDao测试中的bean一直,具体如下:

 

public classNote {
   
@DatabaseField(generatedId= true)
   
private int id;
   
@DatabaseField(index= true)
   
private Stringtext;
   
@DatabaseField(index= true)
   
private Stringcomment;
   
public Note() {
   
}
    public Note(intid) {
       
this.id= id;}
   
public Note(intid, String text, String comment) {
       
this.id= id;
       
this.text= text;
       
this.comment= comment;}
   
public int getId() {
       
return id;}
   
public void setId(intid) {
       
this.id= id;}
   
public StringgetText() {
       
return text;}
   
public void setText(String text) {
       
this.text= text;}
   
public StringgetComment() {
       
return comment;}
   
public void setComment(String comment) {
       
this.comment= comment; }

}

 

2.创建Helper

public  class DatabaseHelper extends OrmLiteSqliteOpenHelper{    private static final String TABLE_NAME = "sqlite-test.db";    private Map<String, Dao> daos = new HashMap<String, Dao>();    private DatabaseHelper(Context context)    {        super(context, TABLE_NAME, null, 4);    }    @Override    public void onCreate(SQLiteDatabase database,                         ConnectionSource connectionSource)    {        try        {            TableUtils.createTable(connectionSource, Note.class);        } catch (SQLException e)        {            e.printStackTrace();        }    }    @Override    public void onUpgrade(SQLiteDatabase database,                          ConnectionSource connectionSource, int oldVersion, int newVersion)    {        try        {            TableUtils.dropTable(connectionSource, Note.class, true);            onCreate(database, connectionSource);        } catch (SQLException e)        {            e.printStackTrace();        }    }    private static DatabaseHelper instance;    public static synchronized DatabaseHelper getHelper(Context context)    {        context = context.getApplicationContext();        if (instance == null)        {            synchronized (DatabaseHelper.class)            {                if (instance == null)                    instance = new DatabaseHelper(context);            }        }        return instance;    }    public synchronized Dao getDao(Class clazz) throws SQLException    {        Dao dao = null;        String className = clazz.getSimpleName();        if (daos.containsKey(className))        {            dao = daos.get(className);        }        if (dao == null)        {            dao = super.getDao(clazz);            daos.put(className, dao);        }        return dao;    }    @Override    public void close()    {        super.close();        for (String key : daos.keySet())        {            Dao dao = daos.get(key);            dao = null;        }    }}

3.创建Dao

public class NoteDao {    private Context context;    private Dao<Note, Integer> userDaoOpe;    private DatabaseHelper helper;    public NoteDao(Context context) {        this.context = context;        try {            helper = DatabaseHelper.getHelper(context);            userDaoOpe = helper.getDao(Note.class);        } catch (SQLException e) {            e.printStackTrace();        }    }    public void add(Note user) {        try {            userDaoOpe.create(user);        } catch (SQLException e) {            e.printStackTrace();        }    }    public List<Note> findAll(){        List<Note> notes=null;        try {          notes = userDaoOpe.queryForAll();        } catch (SQLException e) {            e.printStackTrace();        }        return  notes;    }    public void deleteAll( List<Note> notes){        try {            userDaoOpe.delete(notes);        } catch (SQLException e) {            e.printStackTrace();        }    }}

4.MainActivity

public class MainActivity extends AppCompatActivity {    private NoteDao noteDao = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        noteDao = new NoteDao(this);        new Thread(new Runnable() {            @Override            public void run() {                addNote();               // List<Note> nottt=search();               // delete(nottt);            }        }).start();    }    public void addNote() {        String noteText = "小明";        String comment = "Added on ";        Note note = null;        long  before= Long.valueOf(System.currentTimeMillis());        System.out.println("存储之前的时间为:" +before);        for (int i = 2; i < 10002; i++) {            note = new Note(i, noteText + i, comment);            noteDao.add(note);            note = null;        }        long  after= Long.valueOf(System.currentTimeMillis());        System.out.println("存储之后的时间为:" + after);        System.out.println("插入10000条数据时间差为:" + (after-before));    }    public  List<Note> search(){        long  before= Long.valueOf(System.currentTimeMillis());        System.out.println("查询之前的时间为:" +before);       List<Note> notes= noteDao.findAll();        long  after= Long.valueOf(System.currentTimeMillis());        System.out.println("查询之后的时间为:" + after);        System.out.println("查询10000条数据时间差为:" + (after-before));        return notes;    }    public  void delete(List<Note> notess){        long  before= Long.valueOf(System.currentTimeMillis());        System.out.println("删除之前的时间为:" +before);        noteDao.deleteAll(notess);
        long  after= Long.valueOf(System.currentTimeMillis());        System.out.println("删除之后的时间为:" + after);        System.out.println("删除10000条数据时间差为:" + (after-before));    }}

5.效果比对

分别对10000条、1000条数据先后进行增、查、删操作,效果图如下:

 

三、  Realm

数据库Realm,是用来替代sqlite的一种解决方案,它有一套自己的数据库存储引擎,比sqlite更轻量级,拥有更快的速度,并且具有很多现代数据库的特性,比如支持JSON,流式api,数据变更通知,自动数据同步,简单身份验证,访问控制,事件处理,最重要的是跨平台,目前已有Java,Objective C,Swift,React-Native,Xamarin这五种实现。本测试用的是realm-gradle-plugin:2.2.1"。

1. 创建Bean

首先任然是添加依赖classpath"io.realm:realm-gradle-plugin:2.2.1",以及添加android配置apply plugin: 'realm-android'。再创建实体,继承RealmObject,如下所示:

public classNote extendsRealmObject{
   
public int getId() {
       
return id;
   
}
   
public void setId(intid) {
       
this.id= id;
   
}
   
@PrimaryKey
   
private int id;
   
private String text;
   
private String comment;
   
public Note() {
   
}
    public Note(intid, String text, String comment) {
       
this.id= id;
       
this.text= text;
       
this.comment= comment;
   
}
   
public StringgetText() {
       
return text;
   
}
   
public void setText(String text) {
       
this.text= text;
   
}
   
public StringgetComment() {
       
return comment;
   
}
   
public void setComment(String comment) {
       
this.comment= comment;
   
}
}

2.Realm初始化

注意创建realm实例线程与使用Realm实例线程必须一致且初始化前必须调用Realm.init(Context xxx)。具体代码如下

public  RealmgetRealm(Context context)
{
   
byte[]key =new byte[64];
   
new SecureRandom().nextBytes(key);
   
Realm.init(context);
   
RealmConfiguration config = newRealmConfiguration.Builder()
           
.name("realmdb.realm")//文件名
           
.schemaVersion(0)//版本号
           
.deleteRealmIfMigrationNeeded()//声明版本冲突时自动删除原数据库(当调用了该方法时,上面的方法将失效)。
            .build();//创建
   
return Realm.getInstance(config);
}

3.MainActivity中测试

完整测试代码如下:

 

public classMainActivity extendsAppCompatActivity{
   
Realm myRealm=null;

   
@Override
   
protected void onCreate(BundlesavedInstanceState) {
       
super.onCreate(savedInstanceState);
       
setContentView(R.layout.activity_main);
       
MyThread t1=newMyThread(this);
       
t1.start();



   
}
   
public  RealmgetRealm(Contextcontext)
   
{
        byte[]key =new byte[64];
       
new SecureRandom().nextBytes(key);
       
Realm.init(context);
       
RealmConfiguration config = newRealmConfiguration.Builder()
               
.name("realmdb.realm")//文件名
               
.schemaVersion(0)//版本号
               
.deleteRealmIfMigrationNeeded()//声明版本冲突时自动删除原数据库(当调用了该方法时,上面的方法将失效)。
                .build();//创建
       
return Realm.getInstance(config);
   
}
   
public void addNote(Realm realm){
       
Note book=null;
      
 Longbefore=Long.valueOf(System.currentTimeMillis());
       
System.out.println("存储之前的时间为:"+before);
       
realm.beginTransaction();//必须先开启事务
       
for(inti=0;i<10000;i++){
           
book = new Note();
           
book.setText("司马迁1");
          
 book.setComment("史记2");
           
book.setId(i);
           
realm.copyToRealmOrUpdate(book);
           
book=null;
       
}
       
realm.commitTransaction();//提交事务
       
Long after=Long.valueOf(System.currentTimeMillis());
       
System.out.println("存储之前的时间为:"+after);
       
System.out.println("存储10000条数据时间差为"+(after-before)+"毫秒");
     
/*  Note book1 =realm.where(Note.class).equalTo("id", 5).findFirst();
        if(book1==null){
           System.out.println("*******************"+"--------------------------------");
        }else {
           System.out.println("*******************"+book1.getId());
        }
*/
    }
   
public RealmResults<Note>searchNote(Realm realm){
       
Long before=Long.valueOf(System.currentTimeMillis());
   
    System.out.println("查询之前的时间为:"+before);
       
RealmResults<Note> dogs = realm.where(Note.class).findAll();
       
Long after=Long.valueOf(System.currentTimeMillis());
       
System.out.println("查询之后的时间为:"+after);
       
System.out.println("查询10000条数据时间差为"+(after-before)+"毫秒");
       
System.out.println(dogs.get(9999).getId()+"--------------------------------------");
       
return dogs;
   
}
   
public  void deletAll(RealmResults<Note> books,Realmrealm){
       
Long before=Long.valueOf(System.currentTimeMillis());
       
System.out.println("删除之前的时间为:"+before);
       
realm.beginTransaction();
       
books.deleteAllFromRealm();
       
realm.commitTransaction();
       
Long after=Long.valueOf(System.currentTimeMillis());
       
System.out.println("删除之后的时间为:"+after);
       
System.out.println("删除10000条数据时间差为"+(after-before)+"毫秒");
   
}
   
class MyThreadextendsThread{
       
Context context;
       
public MyThread(){
           
super();
       
}
       
public MyThread(Context context){
           
super();
           
this.context=context;
       
}
       
public void run() {
           
myRealm=getRealm(context);
           
addNote(myRealm);
           
deletAll(searchNote(myRealm),myRealm);
       
}
   
};
}

4.效果对比

 


四、总结

由上述分别采用greendao、ormlite、realm三种数据框架对同一数据结构Note进行10000次和1000次的增、查、删操作,对比其各自的运行效率,其运行速度对比具体如下表所示(时间单位为毫秒):

数据库框架名

添加10000条数据时间

查询10000条数据时间

删除10000条数据时间

添加1000条数据时间

查询1000条数据时间

删除1000条数据时间

Greendao

104666

600

47

11472 

71 

17

Ormlite

140500

2463

269

13892

2671

283

Realm

1597

8

136

327

4

29

上面数据仅表示在增、查、删操作时运行速度的快慢,其他性能、功能、未做对比,对比结果显著,不做详细赘。



3 2
原创粉丝点击