Java实现客户端下载服务器端的数据到sqlite数据库
客户端获取数据时都从服务器上获取,速度会比较慢,所以可以将需要的服务器数据存放到客户端的sqlite数据库中,提高性能。主要的步骤为: “客户端向服务器端请求下载需要的数据”、“服务器端访问数据库,返回数据给客户端”、“客户端解析服务器返回的数据”、“客户端将对应数据库表中的数据全部清空”、“客户端将服务器端返回的数据插入到本地数据库”、“分页下载服务器端的数据”。
1、客户端向服务器端请求下载需要的数据。
Brand brand = new Brand();
brand.setPageIndex(BaseHttpBO.FIRST_PAGE_Index_Default);
brand.setPageSize(BaseHttpBO.PAGE_SIZE_LoadAll);
retrieveNCBaseModel(brand, brandHttpBO, brandSQLiteEvent, isPostDetail);
@Override
protected boolean doRetrieveNAsyncC(int iUseCaseID, BaseModel bm) {
log.info("正在执行BrandHttpBO的retrieveNAsyncC,bm=" +(bm == null ? null : bm.toString()));
RequestBody body = new FormBody.Builder()
.build();
Request req = new Request.Builder()
.url(Configuration.HTTP_IP + Brand.HTTP_BRAND_RetrieveNC + bm.getPageIndex() + Brand.HTTP_BRAND_RETRIEVENC_PageSize + bm.getPageSize())
.addHeader(BaseHttpBO.COOKIE, GlobalController.getInstance().getSessionID())
.post(body)
.build();
HttpRequestUnit hru = new RetrieveNBrandC();
hru.setRequest(req);
hru.setTimeout(TIME_OUT);
hru.setbPostEventToUI(true);
httpEvent.setEventProcessed(false);
httpEvent.setStatus(BaseEvent.EnumEventStatus.EES_Http_ToDo);
hru.setEvent(httpEvent);
HttpRequestManager.getCache(HttpRequestManager.EnumDomainType.EDT_Communication).pushHttpRequest(hru);
log.info("正在发送RN到服务器....");
return true;
}
2、服务器端访问数据库,返回数据给客户端。
DataSourceContextHolder.setDbName(company.getDbName());
List<?> ls = brandBO.retrieveNObject(getStaffFromSession(session).getID(), BaseBO.INVALID_CASE_ID, brand);
logger.info("retrieveAll Brands error code=" + brandBO.getLastErrorCode());
Map<String, Object> params = getDefaultParamToReturn(true);
switch (brandBO.getLastErrorCode()) {
case EC_NoError:
for (Object obj : ls) {
BaseModel bm = (BaseModel) obj;
bm.setSyncDatetime(new Date());
}
params.put("brandList", ls);
params.put("count", brandBO.getTotalRecord());
params.put("msg", "");
params.put("code", "0");
params.put(BaseAction.JSON_ERROR_KEY, EnumErrorCode.EC_NoError.toString());
调用存储过程,主要sql语句:
SET iPageIndex = iPageIndex - 1;
SET recordIndex = iPageIndex * iPageSize;
SELECT F_ID, F_Name
FROM t_brand
WHERE 1 = 1
AND (CASE sName WHEN '' THEN 1=1 ELSE F_Name LIKE CONCAT('%',sName,'%') END)
ORDER BY F_ID DESC
LIMIT recordIndex, iPageSize;
SELECT count(1) into iTotalRecord
FROM t_brand
WHERE 1 = 1
AND (CASE sName WHEN '' THEN 1=1 ELSE F_Name LIKE CONCAT('%',sName,'%') END);
SET iErrorCode := 0;
SET sErrorMsg := '';
3、客户端解析服务器返回的数据。
JSONObject jsonObject = parseError(getResponseData());
if (jsonObject == null || getLastErrorCode() == ErrorInfo.EnumErrorCode.EC_DuplicatedSession) {
break;
}
将jsonObject转为Java对象:
JSONArray jaStaff = jsonObject.getJSONArray(BaseModel.JSON_OBJECTLIST_KEY);
List<BaseModel> brandList = new Brand().parseN(jaStaff);
4、客户端将对应数据库表中的数据全部清空。
@Override
protected boolean refreshByServerDataAsyncC(final int iUseCaseID, final List<?> bmNewList, final BaseSQLiteEvent event) {
log.info("正在进行BrandPresenter的refreshByServerDataAsyncC,bmNewList=" + (bmNewList == null ? null : bmNewList.toString()));
switch (iUseCaseID) {
default:
TaskScheduler.execute(new Runnable() {
@Override
public void run() {
log.info("已经得到服务器返回的需要同步的Brand数据, 准备进行同步...");
// event.setEventTypeSQLite(BaseSQLiteEvent.EnumSQLiteEventType.ESET_Brand_RefreshByServerDataAsync_Done);
event.setLastErrorCode(ErrorInfo.EnumErrorCode.EC_NoError);
//删除本地所有的数据
deleteNSync(iUseCaseID, null);
if (getLastErrorCode() == ErrorInfo.EnumErrorCode.EC_NoError) {
//同步所有服务器返回的数据
createNSync(iUseCaseID, bmNewList);
if (getLastErrorCode() != ErrorInfo.EnumErrorCode.EC_NoError) {
event.setLastErrorCode(ErrorInfo.EnumErrorCode.EC_OtherError);
}
} else {
event.setLastErrorCode(ErrorInfo.EnumErrorCode.EC_OtherError);
}
// event.setLastErrorCode(ErrorInfo.EnumErrorCode.EC_NoError);
event.setStatus(BaseEvent.EnumEventStatus.EES_SQLite_DoneApplyServerData);
//
EventBus.getDefault().post(event);
}
});
break;
}
return true;
}
deleteNSync,清空数据库表brand中的数据:
@Override
protected BaseModel deleteNSync(int iUserCaseID, BaseModel bm) {
log.info("正在进行BrandPresenter的deleteNSync,bm=" + (bm == null ? null : bm.toString()));
try {
dao.getBrandDao().deleteAll();
lastErrorCode = ErrorInfo.EnumErrorCode.EC_NoError;
} catch (Exception e) {
log.info("执行deleteNSync失败,错误信息为" + e.getMessage());
e.printStackTrace();
lastErrorCode = ErrorInfo.EnumErrorCode.EC_OtherError;
}
return null;
}
5、客户端将服务器端返回的数据插入到本地数据库。
createNSync,向数据库表brand插入N条数据:
@Override
protected List<BaseModel> createNSync(int iUseCaseID, final List<?> list) {
log.info("正在进行BrandPresenter的createNSync,list=" + (list == null ? null : list.toString()));
switch (iUseCaseID) {
default:
try {
for (int i = 0; i < list.size(); i++) {
long id = dao.getBrandDao().insert((Brand) list.get(i));
((Brand) list.get(i)).setID(id);
lastErrorCode = ErrorInfo.EnumErrorCode.EC_NoError;
}
} catch (Exception e) {
log.info("执行createNSync时出现异常,错误信息:" + e.getMessage());
e.printStackTrace();
lastErrorCode = ErrorInfo.EnumErrorCode.EC_OtherError;
}
return (List<BaseModel>) list;
}
}
6、分页下载服务器端的数据。
对于数据量比较大的数据,采用分页下载。
设置pageSize为50,每页下载50条疏忽。pageIndex为start,标记为请求第一页:
Commodity commodity = new Commodity();
commodity.setPageIndex(BaseHttpBO.FIRST_PAGE_Index_Default);
commodity.setPageSize(BaseHttpBO.PAGE_SIZE_LoadPageByPage);
commoditySQLiteBO.getSqLiteEvent().setPageIndex(Commodity.PAGEINDEX_START);//...
retrieveNCBaseModel(commodity, commodityHttpBO, commoditySQLiteEvent, isPostDetail);
获取服务器返回的总记录数count,算出一共有totalPageIndex页,记录当前已经下载的页数runTimes,如果已经下载完成,则标记pageIndex为end:
if (baseHttpBO.getHttpEvent().getCount() != null && !"".equals(baseHttpBO.getHttpEvent().getCount())) {
count = Integer.valueOf(baseHttpBO.getHttpEvent().getCount());
int totalPageIndex = count % Integer.valueOf(bm.getPageSize()) != 0 ? count / Integer.valueOf(bm.getPageSize()) + 1 : count / Integer.valueOf(bm.getPageSize());//查询条形码需要totalPageIndex页才能查完
if (runTimes < totalPageIndex) {
bm.setPageIndex(String.valueOf(++runTimes));
// 判断是否为Commodity并且是页数中的最后一页。(为了在present中删除并更新掉z最后一页的所有数据)
if (bm instanceof Commodity && bm.getPageIndex().equals(String.valueOf(totalPageIndex))) {
commoditySQLiteBO.getSqLiteEvent().setPageIndex(Commodity.PAGEINDEX_END);
} else if (bm instanceof Barcodes && bm.getPageIndex().equals(String.valueOf(totalPageIndex))) {
barcodesSQLiteBO.getSqLiteEvent().setPageIndex(Barcodes.PAGEINDEX_END);
}
} else {
break;
}
}
如果是下载第一页数据pageIndex为start,那么找出服务器返回的数据中最小的ID,将小于最小ID的数据全部删除掉。
同理,如果下载的是最后一数据,pageIndex为end,那么需要找出服务器返回的数据中最大的ID,将大于最大ID的数据全部删除掉。
这样做的原因是防止sqlite数据库有残留数据,不在最小ID和最大ID之间的数据应是残留数据:
if (event.getPageIndex() != null && event.getPageIndex().equals(Commodity.PAGEINDEX_START)) {
String sql = "delete from " + getTableName() + " where F_ID > ? ";//
String[] conditions = new String[]{String.valueOf(commodityList.get(0).getID())};
dao.getDatabase().execSQL(sql, conditions);
} else if (event.getPageIndex() != null && event.getPageIndex().equals(Commodity.PAGEINDEX_END)) {
String sql = "delete from " + getTableName() + " where F_ID < ? ";
String[] conditions = new String[]{String.valueOf(commodityList.get(commodityList.size() - 1).getID())};
dao.getDatabase().execSQL(sql, conditions);
}
如果是下载的页数数第一页和最后一页之间,则找出服务器返回的数据中的最大ID和最小ID,删除sqlite数据库中大于最小ID和小于最大ID之间的数据,然后插入新的数据即可:
event.setPageIndex(""); //初始化分页标记
String sql = "delete from " + getTableName() + " where F_ID >= ? and F_ID <= ?";
String[] conditions = new String[]{String.valueOf(commodityList.get(commodityList.size() - 1).getID()), String.valueOf(commodityList.get(0).getID())};
//先删除本地数据库原有的数据
dao.getDatabase().execSQL(sql, conditions);
// 删除从表
for(Commodity commodity : commodityList) {
String sqlCommShopInfo = "delete from " + dao.getCommodityShopInfoDao().getTablename() + " where F_CommodityID = ? ";//
String[] conditionsCommShopInfo = new String[]{String.valueOf(commodity.getID())};
dao.getDatabase().execSQL(sqlCommShopInfo, conditionsCommShopInfo);
}
for (int i = 0; i < commodityList.size(); i++) {
dao.getCommodityDao().insert((Commodity) commodityList.get(i));
List<CommodityShopInfo> commodityShopInfoList = (List<CommodityShopInfo>) commodityList.get(i).getListSlave2();
for(CommodityShopInfo commodityShopInfo : commodityShopInfoList) {
if(commodityShopInfo.getID() != null && commodityShopInfo.getID().intValue() > 0 && dao.getCommodityShopInfoDao().load(commodityShopInfo.getID()) != null) {
dao.getCommodityShopInfoDao().deleteByKey(commodityShopInfo.getID());
}
dao.getCommodityShopInfoDao().insert(commodityShopInfo);
}
}

浙公网安备 33010602011771号