/** * 获取拣货任务信息 * @param cBillcode * @return */ public static TaskInfo_Picking_DB getTaskInfoByCode(String cBillcode) { TaskInfo_Picking_DBDao dao = BaseApplication.getDaoInstant().getTaskInfo_Picking_DBDao(); dao.detachAll();// 不这样,更新的数据字段可能不会被更新到界面上呀 QueryBuilder<TaskInfo_Picking_DB> queryBuilder = dao.queryBuilder(); queryBuilder.where(TaskInfo_Picking_DBDao.Properties.CBillCode.eq(cBillcode)); return queryBuilder.unique(); }
/** * 配置数据库 BaseApplication */ private void setupDatabase() { //创建数据库shop.db DaoMaster.DevOpenHelper helper = new OpenHelper_update(this, "greendao.db", null); //获取可写数据库 SQLiteDatabase db = helper.getWritableDatabase(); //获取数据库对象 DaoMaster daoMaster = new DaoMaster(db); //获取dao对象管理者 daoSession = daoMaster.newSession(IdentityScopeType.Session/*None*/); 更新后内存中的值会更新,否则不会变 } public static DaoSession getDaoInstant() { return daoSession; }
public static void setTaskInfoSubmited(String cBillCode) { BaseApplication.getDaoInstant().getDatabase() .execSQL( MessageFormat.format("update {0} set {1}=1 where {2}=? and {3}>0", TaskInfoDetail_PickingDao.TABLENAME, TaskInfoDetail_PickingDao.Properties.IsSubmited.columnName, TaskInfoDetail_PickingDao.Properties.CBillCode.columnName, TaskInfoDetail_PickingDao.Properties.ScanedCount.columnName ), new Object[]{cBillCode}); TaskInfoDetail_PickingDao dao = BaseApplication.getDaoInstant().getTaskInfoDetail_PickingDao(); dao.detachAll();去缓存 }
/** * Detaches all entities (of type T) from the identity scope (session). Subsequent query results won't return any * previously loaded objects. */ public void detachAll() { if (identityScope != null) { identityScope.clear(); } }
public List<TaskWareList_Picking_DB> getWareListByCustom(String cBillCode) { List<TaskWareList_Picking_DB> list = new ArrayList<>(); Cursor cursor = null; TaskWareList_Picking_DBDao dao = BaseApplication.getDaoInstant().getTaskWareList_Picking_DBDao(); String strSQL = "select T.*,T.[C_BILL_CODE] as parentID, ifnull(iSubCount,0) as iSubCount , T.[N_QNTTY]-b.[iSubCount]\n" + "from TASK_WARE_LIST__PICKING__DB T \n" + "left join (select i_id, sum(I_SCAN_COUNT) as iSubCount from TASK_WARE_INFO__PICKING__DB group by i_id) b on T.[i_id] = b.i_id\n" + "where T.[C_BILL_CODE] = ? \n" + "order by b.iSubCount>0, (T.[N_QNTTY]-b.[iSubCount]) desc, T.[I_ID]"; strSQL = MessageFormat.format(strSQL, String.join(",", dao.getAllColumns())); try { cursor = BaseApplication.getDaoInstant().getDatabase().rawQuery(strSQL, new String[]{cBillCode}); dao.detachAll(); list = dao.loadAllDeepFromCursor(cursor); // while(cursor.moveToNext()) // { // TaskWareList_Picking_DB entity = new TaskWareList_Picking_DB( // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.COrder.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.IID.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.COwnerName.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.CWareCode.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.CWareName.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.CSpec.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.CProducter.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.NQntty.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.CCargoPosStr.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.CLicenseID.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.CSN.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.CBatchNO.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.CProductDate.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.CExp.columnName)), // cursor.getString(cursor.getColumnIndex(TaskWareList_Picking_DBDao.Properties.CBillCode.columnName)) // ); // list.add(entity); // } } catch (Exception ex) { Log.e("getWareListByCustom", ex.getMessage()); } finally { if(cursor != null) { cursor.close(); } } return list; }
GreenDao缓存机制探索
GreenDao是Android中使用比较广泛的一个orm数据库,以高效和便捷著称。在项目开发过程中遇到过好几次特别奇葩的问题,最后排查下来,发现还是由于不熟悉它的缓存机制引起的。下面是自己稍微阅读了下它的源码后做的记录,避免以后发现类似的问题。
缓存机制相关源码
DaoMaster
DaoMaster是GreenDao的入口,它的继承自AbstractDaoMaster,有三个重要的参数,分别是实例、版本和Dao的信息。
//数据库示例
protected final SQLiteDatabase db;
//数据库版本
protected final int schemaVersion;
//dao和daoconfig的配置
protected final Map<Class<? extends AbstractDao<?, ?>>, DaoConfig> daoConfigMap;
DaoMaster中还有两个重要的方法:createAllTables和dropAllTables,和一个抽象的OpenHelper类,该类继承自系统的SQLiteOpenHelper类,主要用于数据库创建的时候初始化所有数据表。
创建DaoMaster需要传入SQLiteDatabase的实例,一般如下创建:
mDaoMaster = new DaoMaster(helper.getWritableDatabase())
跟踪代码可知数据库的初始化和升降级都是在调用helper.getWritableDatabase()时执行的。相关代码在SQLiteOpenHelper类中。
在getWritableDatabase方法中会调用getDatabaseLocked方法
public SQLiteDatabase getWritableDatabase() {
synchronized (this) {
return getDatabaseLocked(true);
}
}
getDatabaseLocked方法如下
private SQLiteDatabase getDatabaseLocked(boolean writable) {
// 首先方法接收一个是否可读的参数
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
//数据库没有打开,关闭并且置空
mDatabase.close().
mDatabase = null;
} else if (!writable || !mDatabase.isReadOnly()) {
//只读或者数据库已经是读写状态了,则直接返回实例
return mDatabase;
}
}
if (mIsInitializing) {
throw new IllegalStateException("getDatabase called recursively");
}
SQLiteDatabase db = mDatabase;
try {
mIsInitializing = true;
if (db != null) {
if (writable && db.isReadOnly()) {
//只读状态的时候打开读写
db.reopenReadWrite();
}
} else if (mName == null) {
db = SQLiteDatabase.create(null);
} else {
//创建数据库实例
。。。代码省略。。。
//调用子类的onConfigure方法
onConfigure(db);
final int version = db.getVersion();
if (version != mNewVersion) {
if (db.isReadOnly()) {
throw new SQLiteException("Can't upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + mName);
}
db.beginTransaction();
try {
if (version == 0) {
// 如果版本为0的时候初始化数据库,调用子类的onCreate方法。
onCreate(db);
} else {
//处理升降级
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
onOpen(db);
if (db.isReadOnly()) {
Log.w(TAG, "Opened " + mName + " in read-only mode");
}
mDatabase