GreenDao、Ormlite、Realm性能对比

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 MainActivity extends AppCompatActivity {
   
private SQLiteDatabase db;
   
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(new Runnable() {
           
@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 class Note {
   
@DatabaseField(generatedId = true)
   
private int id;
   
@DatabaseField(index = true)
   
private Stringtext;
   
@DatabaseField(index = true)
   
private Stringcomment;
   
public Note() {
   
}
    public Note(int id) {
       
this.id = id;}
   
public Note(int id, String text, String comment) {
       
this.id = id;
       
this.text= text;
       
this.comment= comment;}
   
public int getId() {
       
return id;}
   
public void setId(int id) {
       
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 class Note extends RealmObject{
   
public int getId() {
       
return id;
   
}
   
public void setId(int id) {
       
this.id = id;
   
}
   
@PrimaryKey
   
private int id;
   
private String text;
   
private String comment;
   
public Note() {
   
}
    public Note(int id, 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 = new RealmConfiguration.Builder()
           
.name("realmdb.realm") //文件名
           
.schemaVersion(0) //版本号
           
.deleteRealmIfMigrationNeeded()//声明版本冲突时自动删除原数据库(当调用了该方法时,上面的方法将失效)。
            .build();//创建
   
return Realm.getInstance(config);
}

3.MainActivity中测试

完整测试代码如下:

 

public class MainActivity extends AppCompatActivity{
   
Realm myRealm=null;

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



   
}
   
public  Realm getRealm(Contextcontext)
   
{
        byte[]key = new byte[64];
       
new SecureRandom().nextBytes(key);
       
Realm.init(context);
       
RealmConfiguration config = new RealmConfiguration.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(int i=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 MyThreadextends Thread{
       
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

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



猜你喜欢

转载自blog.csdn.net/firesmog/article/details/55656007
今日推荐