一、GreenDao和其他数据库对比
1、GreenDao官方提供的和GreenDao ,OrmLite,ActiveAndroid三者的 性能对比
通过对比,可以看到GreenDao无论在insert、update、query操作中效率都是最高的。
2、GreenDao和Realm性能对比(数据来源)
二、各个数据库的优缺点。
1、 Ormlite
优点:
1.轻量级;
2.使用简单,易上手;
3.封装完善;
4文档完善,使用的项目比较多遇到问题查找比较方便.
缺点:
基于注解和反射,方面效率会受到一些影响(不过要比直接使用SQL效率高)
2、GreenDao
优点:
1、轻量(GreenDao核心类库只有100k左右)
2、效率高、稳定(github上一直在维护更新,现在GreenDao版本已经更新到3.2.2)
3、使用非常简单,上手快,可以自动生成代码
4、支持数据库加密
5、支持缓存(能够将使用的过的实体存在缓存中,下次使用时可以直接从缓存中取,这样可以使性能提高N个数量级)
6、支持与rxjava结合使用
缺点:
文档大部分是英文的
官方对GreenDao性能的描述: Of all ORMs we know, greenDAO is the fastest. greenDAO does not make any compromises regarding performance. Databases are great for storing lots of data, and thus speed matters. Using greenDAO, most entities can be inserted, updated and loaded at rates of several thousand entities per second.
集成过程:
【1】 在项目(project)的gradle中
// In your project build.gradle file:
buildscript {
repositories {
jcenter()
mavenCentral() // add repository
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.0'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
}
}
【2】在应用(Moudle)的gradle中
// In your app projects build.gradle file:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin
dependencies {
compile 'org.greenrobot:greendao:3.2.2' // add library
}
配置数据库的信息
greendao {
schemaVersion 1 // 版本号 升级数据库可以配置
daoPackage 'com.zgl.greentest.gen' // 自动生成的代码的存放包名(可忽略)
targetGenDir 'src/main/java' // 自动生成代码的存放位置(可忽略)
}
使用:
- 1.创建一个bean对象
@Entity
public class Shop{
//表示为购物车列表
public static final int TYPE_CART = 0x01;
//表示为收藏列表
public static final int TYPE_LOVE = 0x02;
//不能用int
@Id(autoincrement = true)
private Long id;
//商品名称
@Unique
private String name;
//商品价格
@Property(nameInDb = "price")
private String price;
//已售数量
private int sell_num;
//图标url
private String image_url;
//商家地址
private String address;
//商品列表类型
private int type;
}
注解含义: @Entity:告诉GreenDao该对象为实体,只有被@Entity注释的Bean类才能被dao类操作 @Id:对象的Id,使用Long类型作为EntityId,否则会报错。(autoincrement = true)表示主键会自增,如果false就会使用旧值 @Property:可以自定义字段名,注意外键不能使用该属性 @NotNull:属性不能为空 @Transient:使用该注释的属性不会被存入数据库的字段中 @Unique:该属性值必须在数据库中是唯一值 @Generated:编译后自动生成的构造函数、方法等的注释,提示构造函数、方法等不能被修改
- 2.初始化greenDao
public class BaseApplication extends Application {
private static BaseApplication mBaseApplication;
private DaoSession mDaoSession;
@Override
public void onCreate() {
super.onCreate();
mBaseApplication = this;
initDataBase();
}
public static BaseApplication instance(){
return mBaseApplication;
}
// 初始化数据库
private void initDataBase() {
//创建数据库shop.db"
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "shop.db", null);
//获取可写数据库
SQLiteDatabase db = helper.getWritableDatabase();
//获取数据库对象
DaoMaster daoMaster = new DaoMaster(db);
//获取Dao对象管理者
daoSession = daoMaster.newSession();
}
public DaoSession getDaoSession() {
return mDaoSession;
}
}
- 3.数据库增删改查
private ShopDao mShopDao = GreenDaoManager.getInstance().getDaoSession().getBookEntityDao();
private Shop dogEntity = new Shop();
private void greenDaoQuery() {
mShopDao.loadAll();
mShopDao.queryBuilder().where(ShopEntityDao.Properties.Price.eq("10"));
}
private void greenDaoUpdate() {
mShopDao.update(dogEntity);
}
private void greenDaoDelete() {
mShopDao.deleteAll();
}
private void greenDaoInsert() {
mShopDao.insert(dogEntity);
}
GreenDao官网
3、Realm
Ream 不是在SQLite基础上的ORM,它有自己的数据查询引擎。所以支持跨平台,也更加高效
优点:
1、支持跨平台(Android,ios,swift)
2、可视化比较好,realm提供了数据库可视化工具
3、效率高(插入和删除数据比GreenDao还要快,但是删除数据会比GreenDao稍慢一些)
4、支持rxjava异步操作
5、支持加密操作
集成过程:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "io.realm:realm-gradle-plugin:3.1.3"
}
}
apply plugin: 'realm-android'
使用:
- 1.创建一个bean
所有realm的bean都需要集成 RealmObject
eg:
public class User extends RealmObject {
private String name; // realm的修饰符支持private public protect
private int age;
@Ignore
private int sessionId;
// Standard getters & setters generated by your IDE…
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public int getSessionId() { return sessionId; }
public void setSessionId(int sessionId) { this.sessionId = sessionId; }
}
注解: @PrimaryKey——表示该字段是主键 @Required——表示该字段非空 @Ignore——表示忽略该字段 被添加@Ignore标签后,存储数据时会忽略该字段。 @Index——添加搜索索引 为字段添加搜索索引,这样会使得插入的速度变慢,数据量也变得更大。不过在查询速度将变得更快,建议只在优化读取性能的特定情况时添加索引
- 2.初始化realm
Realm.init(this);
Realm mRealm = Realm.getDefaultInstance();
也可以配置realm的参数
RealmConfiguration config = new RealmConfiguration.Builder()
.name("myrealm.realm") //文件名
.schemaVersion(0) //版本号
.build();
Realm realm = Realm.getInstance(config);
当使用完毕需要在ondestory()
中关闭realm
@Override
protected void onDestroy() {
super.onDestroy();
// Close the Realm instance.
realm.close();
}
- 3.增删改查
插入数据
realm.executeTransaction(new Realm.Transaction() {
@Overrride
public void execute(Realm realm) {
Dog dog = realm.createObject(Dog.class);
dog.name = "Fido";
dog.age = 5;
}
};
也可以通过这种方式插入数据:
// Obtain a Realm instance
realm.beginTransaction();
User user = realm.createObject(User.class); // Create a new object
user.setName("John");
user.setEmail("john@corporation.com");
realm.commitTransaction();
realm操作的速度比较快,所以对于少量数据在主线程中操作没有太大影响,但是如果数据量大的话就需要在子线程中进行了
realm异步插入数据:
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm bgRealm) {
User user = bgRealm.createObject(User.class);
user.setName("John");
user.setEmail("john@corporation.com");
}
}, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
// Transaction was a success.
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {
// Transaction failed and was automatically canceled.
}
});
查询
RealmResults<User> userList = mRealm.where(User.class).findAll();
异步查询
RealmResults<User> userList = mRealm.where(User.class)
.equalTo("name", "Gavin")
.findAllAsync();
按条件查询
RealmResults<User> userList = mRealm.where(User.class)
.equalTo("name", "Gavin").findAll();
多条件查询
RealmResult<User> r = realm.where(User.class)
.not()
.in("name", new String[]{"Peter", "Jo"})
finalAll();
其他查询条件 sum():对指定字段求和。 average():对指定字段求平均值。 min(): 对指定字段求最小值。 max() : 对指定字段求最大值。count : 求结果集的记录数量。 findAll(): 返回结果集所有字段,返回值为RealmResults队列 findAllSorted() : 排序返回结果集所有字段,返回值为RealmResults队列 between(), greaterThan(),lessThan(), greaterThanOrEqualTo() & lessThanOrEqualTo() equalTo() & notEqualTo() contains(), beginsWith() & endsWith() isNull() & isNotNull() isEmpty()& isNotEmpty()
排序
RealmResults<User> result = realm.where(User.class).findAll();
result = result.sort("age"); // Sort ascending
result = result.sort("age", Sort.DESCENDING);
删除
// obtain the results of a query
final RealmResults<Dog> results = realm.where(Dog.class).findAll();
// All changes to data must happen in a transaction
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
// remove single match
results.deleteFirstFromRealm();
results.deleteLastFromRealm();
// remove a single object
Dog dog = results.get(5);
dog.deleteFromRealm();
// Delete all matches
results.deleteAllFromRealm();
}
});
有关realm的更多操作可以参见这里