现在项目中要用到数据库,最终选择使用了greendao ,至于原因,肯定是性能原因了。本文将着重介绍数据库的异步操作,因为网上很多都是配置集成+简单的使用,并且都还是同步的(重要的是 都是一样的文章!!!)。我想说,如果是百万级的数据就GG了。
一般来说,我们需要数据时,先访问数据库看是否有数据,如果有,就从数据库取,如果没有,就访问网络,成功后,将开启线程将数据插入数据库中,同事更新UI 如下图所示:
1:集成配置
apply plugin: 'org.greenrobot.greendao'
greendao {
schemaVersion 1
daoPackage 'com.app.test.textgreendao.db' //这个填写你自己创建的路径
targetGenDir 'src/main/java'
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'
}
}
dependencies {
compile'org.greenrobot:greendao:3.0.1'
compile'org.greenrobot:greendao-generator:3.0.0'
}
2:接下来就是创建实体类了:
/**
* Created by ${liumengqiang} on 2017/7/10.
*/
@Entity
public class User {
@Id
private long memberId;
@Property
private String name;
@Property
private String age;
}
然后点击 Build —— make build 就是那个绿色小锤子按钮,就会自动帮你生成相应的方法;
至于@Id,@Property 这一类的标记 大家可以上网搜一下 这个不再赘述。
3:然后就是自己封装GreenDao了,首先网上很多都是同步数据 在这里 我用的是异步处理的也就是使用的是AsyncSession类,这个是GreenDao内部封装好的 再次我们可以在封装一下,专门用于异步操作数据库的成功和失败;
首先 我定义了返回操作数据库结果的回调接口
package com.app.test.textgreendao.user;
import java.util.List;
/**
* Created by ${liumengqiang} on 2017/7/12.
*/
public interface UserInterface {
/**
* type true 成功。 false 失败
* @param <T>
*/
interface OnIsertInterface<T>{//单个插入成功
void onIsertInterface(boolean type);
}
interface OnQuerySingleInterface<T>{//单个查询成功
void onQuerySingleInterface(T entry);
}
interface OnDeleteInterface<T>{//单个删除成功
void onDeleteInterface(boolean type);
}
interface OnUpdateInterface<T>{//单个修改成功
void onUpdateInterface(boolean type);
}
interface OnQueryAllInterface<T>{//批量查询数据回调
void onQueryAllBatchInterface(List<T> list);
}
}
然后 我们声明这些接口:
package com.app.test.textgreendao.db;
import com.app.test.textgreendao.user.UserInterface;
/**
* Created by ${liumengqiang} on 2017/7/12.
*/
public class DaoInterface<T> {
protected UserInterface.OnQueryAllInterface<T> onQueryAllInterface;
protected UserInterface.OnUpdateInterface<T> onUpdateInterface;
protected UserInterface.OnIsertInterface<T> onIsertInterface;
protected UserInterface.OnQuerySingleInterface<T> onQuerySingleInterface;
protected UserInterface.OnDeleteInterface<T> onDeleteInterface;
public UserInterface.OnQueryAllInterface<T> getOnQueryAllInterface() {
return onQueryAllInterface;
}
public void setOnQueryAllInterface(UserInterface.OnQueryAllInterface<T> onQueryAllInterface) {
this.onQueryAllInterface = onQueryAllInterface;
}
public UserInterface.OnUpdateInterface<T> getOnUpdateInterface() {
return onUpdateInterface;
}
public void setOnUpdateInterface(UserInterface.OnUpdateInterface<T> onUpdateInterface) {
this.onUpdateInterface = onUpdateInterface;
}
public UserInterface.OnIsertInterface<T> getOnIsertInterface() {
return onIsertInterface;
}
public void setOnIsertInterface(UserInterface.OnIsertInterface<T> onIsertInterface) {
this.onIsertInterface = onIsertInterface;
}
public UserInterface.OnQuerySingleInterface<T> getOnQuerySingleInterface() {
return onQuerySingleInterface;
}
public void setOnQuerySingleInterface(UserInterface.OnQuerySingleInterface<T> onQuerySingleInterface) {
this.onQuerySingleInterface = onQuerySingleInterface;
}
public UserInterface.OnDeleteInterface<T> getOnDeleteInterface() {
return onDeleteInterface;
}
public void setOnDeleteInterface(UserInterface.OnDeleteInterface<T> onDeleteInterface) {
this.onDeleteInterface = onDeleteInterface;
}
}
首先封装一下数据库 DaoManager ,这个网上很多 ,直接看下代码吧
package com.app.test.textgreendao.db;
import android.content.Context;
/**
* Created by ${liumengqiang} on 2017/7/10.
*/
public class DaoManager {
private static DaoManager daoManager;
private DaoMaster daoMaster;
private DaoSession daoSession = null;
private DaoMaster.DevOpenHelper devOpenHelper;
private DaoManager(){};
public static DaoManager getInstance(){
if(daoManager == null){
daoManager = new DaoManager();
}
return daoManager;
}
public DaoMaster getDaoManager(Context context, String DB_NAME){
if(daoMaster == null){
devOpenHelper = new DaoMaster.DevOpenHelper(context, DB_NAME, null);
daoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
}
return daoMaster;
}
public DaoSession getDaoSession(){
if(daoSession == null){
daoSession = daoMaster.newSession();
}
return daoSession;
}
/**
* 关闭DaoSession
*/
private void closeDaoSession(){
if(daoSession != null){
daoSession.clear();
daoSession = null;
}
}
/**
* 关闭Helper
*/
private void closeHelper(){
if(devOpenHelper != null){
devOpenHelper.close();
devOpenHelper = null;
}
}
/**
* 关闭所有的操作
*/
public void closeConnection(){
closeDaoSession();
closeHelper();
}
}
然后就是我们核心部分了,就是处理创建一个类DaoUtils继承UserInterface类,
daoSession.startAsyncSession()返回一个AsyncSession对象,通过该对象我们可以通过setListenerMainThread 方法监听操作数据库的结果, 然后在执行增删改查,比如:asyncSession.queryUnique(query);
package com.app.test.textgreendao.db;
import android.content.Context;
import org.greenrobot.greendao.async.AsyncOperation;
import org.greenrobot.greendao.async.AsyncOperationListener;
import org.greenrobot.greendao.async.AsyncSession;
import org.greenrobot.greendao.query.DeleteQuery;
import org.greenrobot.greendao.query.Query;
import org.greenrobot.greendao.query.WhereCondition;
import java.util.List;
/**
* Created by ${liumengqiang} on 2017/7/11.
*/
public class DaoUtils<T> extends DaoInterface{
private DaoManager daoManager;
public DaoSession daoSession;
public DaoUtils(Context context, String dao_name){
daoManager = DaoManager.getInstance();
daoManager.getDaoManager(context, dao_name);
daoSession = daoManager.getDaoSession();
}
/**
* 条件查询数据
* @param cls
* @return
*/
public <T>void query(Class cls, WhereCondition whereCondition){
AsyncSession asyncSession = daoSession.startAsyncSession();
asyncSession.setListenerMainThread(new AsyncOperationListener() {
@Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
if(operation.isCompletedSucessfully() && onQuerySingleInterface != null){
onQuerySingleInterface.onQuerySingleInterface(operation.getResult());
}else if(onQuerySingleInterface != null){
onQuerySingleInterface.onQuerySingleInterface(null);
}
}
});
Query query = daoSession.queryBuilder(cls).where(whereCondition).build();
asyncSession.queryUnique(query);
}
public T query(Class cls, String whereString, String[] params){
return (T) daoSession.getDao(cls).queryRaw(whereString, params);
}
/**
* 批量查询
* @param object
* @return
*/
public void queryAll(Class object, Query<T> query){
AsyncSession asyncSession = daoSession.startAsyncSession();
asyncSession.setListenerMainThread(new AsyncOperationListener() {
@Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
List<T> result = (List<T>)operation.getResult();
onQueryAllInterface.onQueryAllBatchInterface(result);
}
});
if(query == null){
asyncSession.loadAll(object);
}else{
asyncSession.queryList(query);
}
// return objects;
}
/**
* 删除
*/
public void deleteSingle(T entry){
AsyncSession asyncSession = daoSession.startAsyncSession();
asyncSession.setListenerMainThread(new AsyncOperationListener() {
@Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
if(operation.isCompletedSucessfully() && onDeleteInterface != null){
onDeleteInterface.onDeleteInterface(true);
}else if(onDeleteInterface != null){
onDeleteInterface.onDeleteInterface(false);
}
}
});
asyncSession.delete(entry);
}
/**
* 批量删除
*/
public void deleteBatch(Class cls,final List<T> list){
AsyncSession asyncSession = daoSession.startAsyncSession();
asyncSession.setListenerMainThread(new AsyncOperationListener() {
@Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
if(operation.isCompletedSucessfully() && onDeleteInterface != null){
onDeleteInterface.onDeleteInterface(true);
}else if(onDeleteInterface != null){
onDeleteInterface.onDeleteInterface(false);
}
}
});
asyncSession.deleteInTx(cls, list);
}
/**
* 根据Id单个删除
*/
public void deleteByIdSingle(Class cls,long longParams){//此处longParams数值类型必须为主键id的类型
daoSession.getDao(cls).deleteByKey(longParams);
}
/**
* 根据Id批量删除
*/
public void deleteByIdBatch(Class cls, List<Long> longList){//同上
daoSession.getDao(cls).deleteByKeyInTx(longList);
}
/**
* 删除所有数据
*/
public void deleteAll(Class cls){
final AsyncSession asyncSession = daoSession.startAsyncSession();
asyncSession.setListenerMainThread(new AsyncOperationListener() {
@Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
if(operation.isCompletedSucessfully() && onDeleteInterface != null){
onDeleteInterface.onDeleteInterface(true);
}else if(onDeleteInterface != null){
onDeleteInterface.onDeleteInterface(false);
}
}
});
asyncSession.deleteAll(cls);
}
/**
* 插入一条数据
*/
public void insertSingle(final T entity){
AsyncSession asyncSession = daoSession.startAsyncSession();
asyncSession.setListenerMainThread(new AsyncOperationListener() {
@Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
if(operation.isCompletedSucessfully() && onIsertInterface != null){
onIsertInterface.onIsertInterface(true);
}else if(onIsertInterface != null){
onIsertInterface.onIsertInterface(false);
}
}
});
asyncSession.runInTx(new Runnable() {
@Override
public void run() {
daoSession.insert(entity);
}
});
}
/**
* 批量插入
*/
public <T>void insertBatch(final Class cls,final List<T> userList){
AsyncSession asyncSession = daoSession.startAsyncSession();
asyncSession.setListenerMainThread(new AsyncOperationListener() {
@Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
if(operation.isCompletedSucessfully() && onIsertInterface != null){
onIsertInterface.onIsertInterface(true);
}else if(onIsertInterface != null){
onIsertInterface.onIsertInterface(false);
}
}
});
asyncSession.runInTx(new Runnable() {
@Override
public void run() {
for (T object : userList) {
daoSession.insertOrReplace(object);
}
}
});
}
/**
* 更新一个数据
*/
public <T>void updateSingle(Class cls,T entry){
AsyncSession asyncSession = daoSession.startAsyncSession();
asyncSession.setListenerMainThread(new AsyncOperationListener() {
@Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
if(operation.isCompletedSucessfully() && onUpdateInterface != null){
onUpdateInterface.onUpdateInterface(true);
}else if(onUpdateInterface != null){
onUpdateInterface.onUpdateInterface(false);
}
}
});
asyncSession.update(entry);
}
/**
* 批量更新数据
*/
public <T>void updateBatch(final Class cls, final List<T> tList){
AsyncSession asyncSession = daoSession.startAsyncSession();
asyncSession.setListenerMainThread(new AsyncOperationListener() {
@Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
if(operation.isCompletedSucessfully() && onUpdateInterface != null){
onUpdateInterface.onUpdateInterface(true);
}else if(onUpdateInterface != null){
onUpdateInterface.onUpdateInterface(false);
}
}
});
asyncSession.updateInTx(cls, tList);
}
}
上面的核心类,有几个我搞的不太懂 就是那个根据id删除的,如何整成异步的;再有就是删除异步里面的迭代器我不太会用。小伙伴们知道的话 可以交流沟通一下。
由于greendao是通过类的不同来识别的,所以当我们操作不同表时,都创建一个相应的操作数据库Utils 继承自DaoUtils。比如我创建的User类 就可以创建一个相应的操作数据库utils类如下:
package com.app.test.textgreendao.user;
import android.content.Context;
import com.app.test.textgreendao.db.DaoUtils;
import com.app.test.textgreendao.db.UserDao;
import org.greenrobot.greendao.async.AsyncOperation;
import org.greenrobot.greendao.async.AsyncOperationListener;
import org.greenrobot.greendao.async.AsyncSession;
import org.greenrobot.greendao.query.Query;
import java.util.ArrayList;
import java.util.List;
/**
* Created by ${liumengqiang} on 2017/7/11.
*/
public class UserDaoUtils extends DaoUtils<User>{
public UserDaoUtils(Context context, String dao_name) {
super(context, dao_name);
}
/**
* 单个插入
* @param user
*/
public void insertUser(User user){
insertSingle(user);
}
/**
* 批量插入
*/
public void insertBatchUser(List<User> list){
insertBatch(User.class,list);
}
/**
* 条件查询
*/
public void queryWhereUser(long memberId){
query(User.class, UserDao.Properties.MemberId.eq(memberId));
}
/**
* 查询全部
*/
public void queryAllUser(){
queryAll(User.class, null);
// return users;
}
/**
* 条件删除
*/
public void deleteSingleUser(long memberId){
User user = new User();
user.setMemberId(memberId);
deleteSingle(user);
}
/**
* 批量删除
*/
public void deleteBatchUser(List<Integer> integerList){
List<User> userList = new ArrayList<>();
for(int i = 0;i < integerList.size(); i++){
User user = new User();
user.setMemberId(integerList.get(i));
userList.add(user);
}
deleteBatch(User.class, userList);
}
/**
* 单个更新
*/
public void updateSingleUser(User user){
updateSingle(User.class, user);
}
/**
* 批量更新
*/
public void updateBatchUser(List<User> list){
updateBatch(User.class,list);
}
/**
* 根据Id 单个删除
*/
public void deleteByIdSingleUser(long memberId){
deleteByIdSingle(User.class, memberId);
}
/**
* 根据Id批量删除
*/
public void deleteByIdBatchUser(List<Long> longList){
deleteByIdBatch(User.class, longList);
}
/**
* 删除所有
*/
public void deleteAll(){
deleteAll(User.class);
}
/**
* 条件批量删除
*/
public void deleteWhereBatch(String ageString){
Query<User> build = daoSession.queryBuilder(User.class).where(UserDao.Properties.Age.eq(ageString)).build();
AsyncSession asyncSession = daoSession.startAsyncSession();
asyncSession.setListenerMainThread(new AsyncOperationListener() {
@Override
public void onAsyncOperationCompleted(AsyncOperation operation) {
if(operation.isCompletedSucessfully()){
deleteBatch(User.class, (List<User> )operation.getResult());
}
}
});
asyncSession.queryList(build);
}
}
当我们需要在view层操作数据库的结果时,比如插入结果,我们可以通过:
userDaoUtils = new UserDaoUtils(getApplicationContext(), "123456789");
userDaoUtils.setOnIsertInterface(new UserInterface.OnIsertInterface() {
@Override
public void onIsertInterface(boolean type) {
if(type){
/**
* 插入一条数据成功
*/
}
}
});
这样是不是方便多了。
其次有几个坑大家共勉:
1: 删除数据时, greendao是根据Id进行删除的。
2:添加或删除字段时,需要删除重新安装apk
3: 创建的实体类 ,不要创建成内部类。
最后附上源码地址:
http://download.youkuaiyun.com/download/lmq121210/9897747