greenDAO的本质是向关系数据库SQLite中存储的数据提供面向对象的接口。仅定义数据模型,greenDAO将创建Java数据对象(实体)和DAOs(数据访问对象)。这将为您节省大量枯燥的代码,只需来回移动数据。除此之外,greenDAO还提供了一些高级的ORM特性,比如会话缓存、热切加载和活动实体。
在我们所知道的所有ORMs中,greenDAO是最快的。greenDAO并没有对性能做出任何妥协。数据库非常适合存储大量数据,因此速度很重要。使用greenDAO,大多数实体可以被插入、更新和加载数千个实体每秒的速率。
我们对greenDAO的表现充满信心,并邀请您将greenDAO与其他ORMs进行比较。我们开放了我们的基准,以实现完全透明。下面的图表比较了3个最流行的ORM解决方案,分别是Android greenDAO、orlite和ActiveAndroid(根据GitHub星和Appbrain的统计数据)。greenDAO插入和更新实体的速度快2倍,并且加载实体的速度比orlite快4倍。对于典型应用,加载速度是最相关的。
GitHub:https://github.com/greenrobot/greenDAO
官网介绍:http://greenrobot.org/greendao/features/
jar仓库:http://search.maven.org/#search%7Cga%7C1%7Cgreendao
这篇博客的测试代码:http://download.csdn.net/download/qq_16064871/9976800
1、配置
GitHub官方配置如下:
// In your root build.gradle file: buildscript { repositories { jcenter() mavenCentral() // add repository } dependencies { classpath 'com.android.tools.build:gradle:2.3.1' classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin } }
// 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 }
根据我们具体情况,会加上版本控制,以及注解生成实体类的路径
apply plugin: 'com.android.application' apply plugin: 'org.greenrobot.greendao' greendao { schemaVersion 1 daoPackage 'com.example.database' targetGenDir 'src/main/java' }
2、注解字段说明
大家都知道使用 greendao-api 包进行注解生成实体类。那么就看看注解的意思。
@Entity 定义实体
@nameInDb 在数据库中的名字,如不写则为实体中类名
@indexes 索引
@createInDb 是否创建表,默认为true,false时不创建
@schema 指定架构名称为实体
@active 无论是更新生成都刷新
@Id
@NotNull 不为null
@Unique 唯一约束
@ToMany 一对多
@OrderBy 排序
@ToOne 一对一
@Transient 不存储在数据库中
@generated 由greendao产生的构造函数或方法
注意事项:
官方文档上写的是,id可以是long或者是Long,但是在java中long默认会赋初值,不会给null,所以我们在这里要使用Long,然后在插入记录的时候赋值为null,或者干脆这么写:
注意,我创建对象的都是数据都是set进去的,所以这么写稍微简单些,如果是创建对象的时候构造方法里面传入数值,那么创建的时候id位置直接写null就行了。
小结:如果仅仅是作为id使用,那么用long和Long都行,如果是自增长的,必须使用Long。
另外float类型也是使用建议使用小写的,使用大写时候,如果为空会出问题。
3、查询
Query类代表着一个查询,可被执行多次。但使用QueryBuilder的方法之一(如list())获取一个结果时,QueryBuilder内部就是使用Query类。如果要多次执行相同的请求,可调用QueryBulder的build()方法创建一个查询而非执行它。
greenDAO同时支持获取单个结果(0或者1个结果)和结果列表。若期待获取一个结果可以调用Query(或QueryBulder)的unique(),这将返回一个结果或匹配不到返回null。若不允许返回nul,可调用uniqueOrThrow(),它将保证返回一个非null实体(否则会抛出一个DaoException)。
若期待返回多个结果,可以调用下面的list...方法:
list() 所有实体载入内存,以ArrayList形式返回,使用最简单。
listLazy() 实体按需加载到内存。当列表中的其中一个元素第一次被访问,它会被加载并缓存备将来使用。使用完必须关闭。
listLazyUncached() 一个“虚拟”的实体列表:任何访问列表中的元素都会从数据库中读取。使用完必须关闭。
listIterator 可迭代访问结果集,按需加载数据,数据不缓存。使用完必须关闭。
方法listLazy,listLazyUncached和 listIterator需使用greenDAO的LazyList类。LazyList持有一个数据库游标,可按需加载数据。这也是为什么必须确保关闭懒加载列表和迭代器(通常使用try/finally包裹)。listLazy()的懒加载列表和listIterator()懒加载迭代器,在所有元素被访为或遍历后自动关闭游标。但是,还是必须调用close()方法,防止list的执行过早结束。
4、增删改查部分代码示例
@Override public void onClick(View v) { String temp =""; switch (v.getId()){ case R.id.button: //普通添加数据,没有做线程处理,有一点点卡 for (int i = 0; i<100 ; i++ ){ User user = new User(); user.setStrjob("工作" + i); user.setStrName("姓名" + i); Long ID = GreenDaoManager.getInstance().getUserDao().insert(user); } temp = "总共" + GreenDaoManager.getInstance().getUserDao().count()+"条数据"; break; case R.id.button1: //事务添加数据 List<User> list = new LinkedList<>(); for (int i = 0; i<100 ; i++ ){ User user = new User(); user.setStrjob("工作" + i); user.setStrName("姓名" + i); list.add(user); } GreenDaoManager.getInstance().getUserDao().insertInTx(list); temp = "总共" + GreenDaoManager.getInstance().getUserDao().count()+"条数据"; break; case R.id.button2: //条件查询 Query<User> queue = GreenDaoManager.getInstance().getUserDao().queryBuilder() .where(UserDao.Properties.StrName.eq("姓名1")).build(); temp = "查询" +queue.listLazy().size()+"条数据"; break; case R.id.button3: //查询所有的数据 方式一 QueryBuilder<User> queueAll = GreenDaoManager.getInstance().getUserDao().queryBuilder(); temp = "查询" + queueAll.listLazy().size()+"条数据"; //查询所有的数据 方式二 List<User> list1 = GreenDaoManager.getInstance().getUserDao().loadAll(); break; case R.id.button4: // // GreenDaoManager.getInstance().getUserDao().update(); //更新单个数据 // GreenDaoManager.getInstance().getUserDao().updateInTx(); //批量更新 break; } mshouTextView.setText(temp); }
5、数据库自定义名字以及存储位置
进行了简单的封装
package com.example.utils; import android.content.ContextWrapper; import android.database.DatabaseErrorHandler; import android.database.sqlite.SQLiteDatabase; import com.example.database.DaoMaster; import com.example.database.DaoSession; import com.example.database.TeacherDao; import com.example.database.UserDao; import java.io.File; import java.io.IOException; public class GreenDaoManager { private volatile static GreenDaoManager mInstance = null; private DaoSession mDaoSession; public static GreenDaoManager getInstance() { if (mInstance == null) { synchronized (GreenDaoManager.class){ if(mInstance == null){ mInstance = new GreenDaoManager(); } } } return mInstance; } //自定义数据库存储位置 public void getGreenDaoSession(final String dirpath, String filename) { try{ ContextWrapper wrapper = new ContextWrapper(null) { @Override public File getDatabasePath(String name) { boolean sdExist = android.os.Environment.MEDIA_MOUNTED.equals(android.os.Environment.getExternalStorageState()); if (!sdExist) { return null; } else { String dbPath = dirpath + "/" + name; File dirFile = new File(dirpath); if (!dirFile.exists()) dirFile.mkdirs(); boolean isFileCreateSuccess = false; File dbFile = new File(dbPath); if (!dbFile.exists()) { try { isFileCreateSuccess = dbFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } else isFileCreateSuccess = true; if (isFileCreateSuccess) return dbFile; else return super.getDatabasePath(name); } } @Override public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) { return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null); } @Override public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) { return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null); } }; DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(wrapper,filename,null); mDaoSession = new DaoMaster(devOpenHelper.getWritableDatabase()).newSession(); }catch (Exception e){ e.printStackTrace(); } } public UserDao getUserDao() { return mDaoSession.getUserDao(); } public TeacherDao getTeacherDao() { return mDaoSession.getTeacherDao(); } }
界面简单显示
使用3.2以上版本(不包含3.2),要重新配置grade版本,貌似是兼容性问题。