greenDAO是一个将对象映射到SQLite数据库中的轻量且快速的ORM解决方案。
关于greenDAO可以看官网 官网地址
github地址
greenDAO 优势
- 一个精简的库
- 性能最大化
- 内存开销最小化
- 易于使用的 APIs
- 对 Android 进行高度优化
首先,我们先简单集成 greenDAO:
1、在项目的 build.gradle 中加入远程仓库及插件:
1 2 3 4 5 6 7 8 9 10
| buildscript { repositories { jcenter() mavenCentral() // add repository } dependencies { classpath 'com.android.tools.build:gradle:2.3.3' classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin } }
|
2、在 module 中的 build.gradle 中顶部引入插件,然后加入 library 依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13
| apply plugin: 'com.android.application' apply plugin: 'org.greenrobot.greendao' // apply plugin
android { ... }
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:26.+'
compile 'org.greenrobot:greendao:3.2.0' // add library }
|
然后我们Sync Now
之后就集成完成,当然我们还需要配置一下相关路径
3、自定义路径
在 module 中的 build.gradle 中最外层加入如下:
1 2 3 4 5
| greendao { schemaVersion 1 daoPackage 'sing.greendao.db' targetGenDir 'src/main/java' }
|
- schemaVersion,指定数据库schema版本号,升级等操作会用到
- daoPackage,dao的包名,包名默认是entity所在的包
- targetGenDir,生成数据库文件的目录
4、创建一个实体类 User
1 2 3 4 5 6 7 8 9 10
| @Entity public class User {
@Id private Long id;
@NotNull private String name; private int age; }
|
然后我们在工具栏中找到 Build
–>Make Module 'app'
,执行之后可以看到在我们指定的路径下会生成3个类:

5、greenDAO的使用
首先在 Application 中初始化并提供 DaoSession 的获取方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class App extends Application {
private DaoSession daoSession; @Override public void onCreate() { super.onCreate();
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "notes-db"); Database db = helper.getWritableDb(); daoSession = new DaoMaster(db).newSession(); }
public DaoSession getDaoSession() { return daoSession; } } ```
当我们使用的时候,在 Acticity 中首先要通过 DaoSession 获取到 UserDao:
```JAVA DaoSession daoSession = ((App) getApplication()).getDaoSession(); UserDao dao = daoSession.getUserDao();
|
1 2 3 4
| User user = new User(); user.setAge(Integer.valueOf(age)); user.setName(name); dao.insert(user);
|
1 2 3 4
| User user = list.get(position); Long noteId = user.getId(); dao.deleteByKey(noteId);
|
1 2 3 4
| User user = list.get(position); user.setName(name); user.setAge(Integer.valueOf(age)); dao.update(user);
|
1 2 3
| List<User> notes = notesQuery.list(); List<User> notes = dao.loadAll(); List<User> notes = dao.load(key);
|
6、greenDAO中的注解
- @Entity 定义实体
@nameInDb 在数据库中的名字,如不写则为实体中类名
@indexes 索引
@createInDb 是否创建表,默认为true,false时不创建
@schema 指定架构名称为实体
@active 无论是更新生成都刷新
- @Id
- @NotNull 不为null
- @Unique 唯一约束
- @ToMany 一对多
- @OrderBy 排序
- @ToOne 一对一
- @Transient 不存储在数据库中
- @generated 由greendao产生的构造函数或方法
7、API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| void attachEntity(T entity): long count():获取数据库中数据的数量
void delete(T entity):从数据库中删除给定的实体 void deleteAll() :删除数据库中全部数据 void deleteByKey(K key):从数据库中删除给定Key所对应的实体 void deleteByKeyInTx(java.lang.Iterable<K> keys):使用事务操作删除数据库中给定的所有key所对应的实体 void deleteByKeyInTx(K... keys):使用事务操作删除数据库中给定的所有key所对应的实体 void deleteInTx(java.lang.Iterable<T> entities):使用事务操作删除数据库中给定实体集合中的实体 void deleteInTx(T... entities):使用事务操作删除数据库中给定的实体
long insert(T entity):将给定的实体插入数据库 void insertInTx(java.lang.Iterable<T> entities):使用事务操作,将给定的实体集合插入数据库 void insertInTx(java.lang.Iterable<T> entities, boolean setPrimaryKey):使用事务操作,将给定的实体集合插入数据库,并设置是否设定主键 void insertInTx(T... entities):将给定的实体插入数据库 long insertOrReplace(T entity):将给定的实体插入数据库,若此实体类存在,则覆盖 void insertOrReplaceInTx(java.lang.Iterable<T> entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖 void insertOrReplaceInTx(java.lang.Iterable<T> entities, boolean setPrimaryKey):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖并设置是否设定主键 void insertOrReplaceInTx(T... entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则覆盖 long insertWithoutSettingPk(T entity):将给定的实体插入数据库,但不设定主键
void save(T entity):将给定的实体插入数据库,若此实体类存在,则更新 void saveInTx(java.lang.Iterable<T> entities):将给定的实体插入数据库,若此实体类存在,则更新 void saveInTx(T... entities):使用事务操作,将给定的实体插入数据库,若此实体类存在,则更新
T load(K key):加载给定主键的实体 java.util.List<T> loadAll():加载数据库中所有的实体 protected java.util.List<T> loadAllAndCloseCursor(android.database.Cursor cursor) :从cursor中读取、返回实体的列表,并关闭该cursor protected java.util.List<T> loadAllFromCursor(android.database.Cursor cursor):从cursor中读取、返回实体的列表 T loadByRowId(long rowId) :加载某一行并返回该行的实体 protected T loadUnique(android.database.Cursor cursor) :从cursor中读取、返回唯一实体 protected T loadUniqueAndCloseCursor(android.database.Cursor cursor) :从cursor中读取、返回唯一实体,并关闭该cursor
void update(T entity) :更新给定的实体 protected void updateInsideSynchronized(T entity, DatabaseStatement stmt, boolean lock) protected void updateInsideSynchronized(T entity, android.database.sqlite.SQLiteStatement stmt, boolean lock) void updateInTx(java.lang.Iterable<T> entities) :使用事务操作,更新给定的实体 void updateInTx(T... entities):使用事务操作,更新给定的实体
|
8、封装
我们换一种写法,在第4部做完之后不在 Application 中初始化,而在使用的时候进行初始化,我们创建 DbManager.java 来进行管理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
public class DbManager { private static final String DB_NAME = "dataa.db"; private volatile static DbManager mDaoManager; private static DaoMaster.DevOpenHelper mHelper; private static DaoMaster mDaoMaster; private static DaoSession mDaoSession; private Context context;
public static DbManager getInstance() { DbManager instance = null; if (mDaoManager == null) { synchronized (DbManager.class) { if (instance == null) { instance = new DbManager(); mDaoManager = instance; } } } return mDaoManager; }
public DbManager init(Context context) { this.context = context; return mDaoManager; }
public DaoMaster getDaoMaster() { if (null == mDaoMaster) { mHelper = new DaoMaster.DevOpenHelper(context, DB_NAME, null); mDaoMaster = new DaoMaster(mHelper.getWritableDatabase()); } return mDaoMaster; }
public DaoSession getDaoSession() { if (null == mDaoSession) { if (null == mDaoMaster) { mDaoMaster = getDaoMaster(); } mDaoSession = mDaoMaster.newSession(); } return mDaoSession; }
public void setDebug(boolean flag) { QueryBuilder.LOG_SQL = flag; QueryBuilder.LOG_VALUES = flag; }
public void closeDataBase() { closeHelper(); closeDaoSession(); }
public void closeDaoSession() { if (null != mDaoSession) { mDaoSession.clear(); mDaoSession = null; } }
public void closeHelper() { if (mHelper != null) { mHelper.close(); mHelper = null; } } }
|
然后我们创建 BaseDao.java 来封装使用的增、删、改、查,而且在他的继承类中可以方便扩展:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
| public class BaseDao<T>{ public static final String TAG = BaseDao.class.getSimpleName(); public static final boolean DUBUG = true; public DbManager manager; public DaoSession daoSession;
public BaseDao(Context context) { manager = DbManager.getInstance().init(context); daoSession = manager.getDaoSession(); manager.setDebug(DUBUG); }
public boolean insert(T object){ boolean flag = false; try { flag = manager.getDaoSession().insert(object) != -1 ? true:false; } catch (Exception e) { Log.e(TAG, e.toString()); } return flag; }
public boolean insert(final List<T> objects){ boolean flag = false; if (null == objects || objects.isEmpty()){ return false; } try { manager.getDaoSession().runInTx(new Runnable() { @Override public void run() { for (T object : objects) { manager.getDaoSession().insertOrReplace(object); } } }); flag = true; } catch (Exception e) { Log.e(TAG, e.toString()); flag = false; }finally {
} return flag; }
public void update(T object){ if (null == object){ return ; } try { manager.getDaoSession().update(object); } catch (Exception e) { Log.e(TAG, e.toString()); } }
public void update(final List<T> objects, Class clss){ if (null == objects || objects.isEmpty()){ return; } try { daoSession.getDao(clss).updateInTx(new Runnable() { @Override public void run() { for(T object:objects){ daoSession.update(object); } } }); } catch (Exception e) { Log.e(TAG, e.toString()); } }
public boolean deleteTable(Class clss){ boolean flag = false; try { manager.getDaoSession().deleteAll(clss); flag = true; } catch (Exception e) { Log.e(TAG, e.toString()); flag = false; } return flag; }
public void delete(T object){ try { daoSession.delete(object); } catch (Exception e) { Log.e(TAG, e.toString()); } }
public boolean delete(final List<T> objects, Class clss){ boolean flag = false; if (null == objects || objects.isEmpty()){ return false; } try { daoSession.getDao(clss).deleteInTx(new Runnable() { @Override public void run() { for(T object:objects){ daoSession.delete(object); } } }); flag = true; } catch (Exception e) { Log.e(TAG, e.toString()); flag = false; } return flag; }
public void deleteById(long id,Class clss){ daoSession.getDao(clss).deleteByKey(id); }
public String getTableName(Class object){ return daoSession.getDao(object).getTablename(); }
public boolean isExitObject(long id, Class object){ QueryBuilder<T> qb = (QueryBuilder<T>) daoSession.getDao(object).queryBuilder(); qb.where(UserDao.Properties.Id.eq(id)); long length = qb.buildCount().count(); return length>0 ? true:false; }
public T queryById(long id,Class object){ return (T) daoSession.getDao(object).loadByRowId(id); }
public List<T> queryObject(Class object,String where,String...params){ Object obj = null; List<T> objects = null; try { obj = daoSession.getDao(object); if (null == obj){ return null; } objects = daoSession.getDao(object).queryRaw(where,params); } catch (Exception e) { Log.e(TAG, e.toString()); }
return objects; } public List<T> queryAll(Class object){ List<T> objects = null; try { objects = (List<T>) daoSession.getDao(object).loadAll(); } catch (Exception e) { Log.e(TAG,e.toString()); } return objects; }
public void closeDataBase(){ manager.closeDataBase(); } }
|
之后我们所有的实现类都继承此类即可,需要重写的部分重写,比如简单的:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class UserDaoImpl extends BaseDao<User> { public UserDaoIml(Context context) { super(context); }
@Override public boolean isExitObject(long id, Class object) { QueryBuilder<User> qb = (QueryBuilder<User>) daoSession.getDao(object).queryBuilder(); qb.where(UserDao.Properties.Id.eq(id)); long length = qb.buildCount().count(); return length > 0 ? true : false; } }
|
然后我们就可以在 Activity 中使用所以的方法:
1 2 3 4 5 6
| UserDaoImpl userDaoIml = new UserDaoImpl(this);
userDaoImpl.insert(user); userDaoImpl.delete(user); userDaoImpl.update(user); userDaoImpl.queryAll(User.class)
|
而且我们也封装了事务处理,支持批量操作,是不是很方便?
由上我们增加了3条数据,然后我们将数据库导出查看:

然后我们演示一下更新和删除操作

demo下载地址