在 android 中使用批处理操作在 sqlite 中插入数据
inserting data in sqlite using batch operation in android
我正在使用改造从 Web 服务获取记录。获取记录不需要太多时间,但插入本地数据库需要几分钟。我尝试使用批处理操作插入它,但我没有观察到很大的不同。下面是我的网络服务响应和数据库插入方法。请检查我哪里出错了。
private void getResponseAndInsert(){
progressDialog = createProgressDialog(getActivity(), false);
progressDialog.show();
final ContentServiceCall request = ServiceGenerator.createService(ContentServiceCall.class, "Empty");
final Call<VODServiceResponse> call = request.getAllVODCategories(Constants.WS_VERSION,Constants.LOCAL_EN,Constants.PLATFORM);
call.enqueue(new Callback<VODServiceResponse>() {
@Override
public void onResponse(Call<VODServiceResponse> call, final Response<VODServiceResponse> response) {
if(response!=null && response.isSuccessful())
{
if(response.body()!=null && response.body().getResponse()!=null)
{
if(response.body().getResponse().getResponseCode()== Constants.RESPONSE_CODE_SUCCESS)
{
if(response.body().getVODCategories() != null)
{
VODCategories vodCategories;
for (int i = 0; i < response.body().getVODCategories().size(); i++) {
//inserting in vod categories
vodCategories = response.body().getVODCategories().get(i);
dbHelper.insertVODCategories(vodCategories);
}
}
else {
// No data returned etc
}
}
else
{
//response.body().getResponse().getMessage() display in toast
//Toast.makeText(getActivity(),response.body().getResponse().getMessage(),Toast.LENGTH_LONG).show();
}
}
else
{
// leave it
}
}
else
{
// Display proper message
}
progressDialog.dismiss();
}
@Override
public void onFailure(Call<VODServiceResponse> call, Throwable t) {
Log.e("Fail", "Failure");
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
//Toast.makeText(getActivity(),"Please Check your Internet Connection ",Toast.LENGTH_LONG).show();
}
});
}
数据库插入方式
public boolean insertVODCategories(VODCategories vd) {
db = this.getWritableDatabase();
db.beginTransaction();
try {
ContentValues initialValues = new ContentValues();
initialValues.put(VODCATEGORIES_COLUMN_VODPARENTCATGORYID, vd.getVODParentCategoryId());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYID, vd.getVODCategoryId());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYNAME, vd.getVODCategoryName());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYTHUMBNAILPATH, vd.getVODCategoryThumbnailPath());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYIMAGEPATH, vd.getVODCategoryImagePath());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYIMAGEPATHLARGE, vd.getVODCategoryImagePathLarge());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYDESCRIPTION, vd.getVODCategoryDescription());
initialValues.put(VODCATEGORIES_COLUMN_VODADDEDDATE, vd.getVODCategoryAddedDate());
db.insert(TABLE_VODCATEGORIES, null, initialValues);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
return true;
}
}
您使用的批处理操作有误。您正在数据库事务中执行单个插入,这使得该事务无用。一个事务的重点是做多个操作。
你可以这样做:
List<VODCategories categories = response.body().getVODCategories();
List<ContentValues> valuesList = new ArrayList<>();
VODCategories vd;
for (int i = 0; i < categories.size(); i++) {
vd = categories.get(i);
ContentValues initialValues = new ContentValues();
initialValues.put(VODCATEGORIES_COLUMN_VODPARENTCATGORYID, vd.getVODParentCategoryId());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYID, vd.getVODCategoryId());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYNAME, vd.getVODCategoryName());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYTHUMBNAILPATH, vd.getVODCategoryThumbnailPath());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYIMAGEPATH, vd.getVODCategoryImagePath());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYIMAGEPATHLARGE, vd.getVODCategoryImagePathLarge());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYDESCRIPTION, vd.getVODCategoryDescription());
initialValues.put(VODCATEGORIES_COLUMN_VODADDEDDATE, vd.getVODCategoryAddedDate());
valuesList.add(initialValues);
}
dbHelper.insertVODCategories(valuesList);
为所有对象创建一个 ContentValues
的列表,然后
public boolean insertVODCategories(List<ContentValues> values) {
db = this.getWritableDatabase();
db.beginTransaction();
try {
for(int i = 0; i < values.size(); i++) {
db.insert(TABLE_VODCATEGORIES, null, values.get(i));
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
return true;
}
}
在单个事务中插入所有这些值,这应该会更快。
同样onResponse
在主线程上执行。您可能希望在后台线程上执行数据库操作,这样就不会阻塞 UI.
我正在使用改造从 Web 服务获取记录。获取记录不需要太多时间,但插入本地数据库需要几分钟。我尝试使用批处理操作插入它,但我没有观察到很大的不同。下面是我的网络服务响应和数据库插入方法。请检查我哪里出错了。
private void getResponseAndInsert(){
progressDialog = createProgressDialog(getActivity(), false);
progressDialog.show();
final ContentServiceCall request = ServiceGenerator.createService(ContentServiceCall.class, "Empty");
final Call<VODServiceResponse> call = request.getAllVODCategories(Constants.WS_VERSION,Constants.LOCAL_EN,Constants.PLATFORM);
call.enqueue(new Callback<VODServiceResponse>() {
@Override
public void onResponse(Call<VODServiceResponse> call, final Response<VODServiceResponse> response) {
if(response!=null && response.isSuccessful())
{
if(response.body()!=null && response.body().getResponse()!=null)
{
if(response.body().getResponse().getResponseCode()== Constants.RESPONSE_CODE_SUCCESS)
{
if(response.body().getVODCategories() != null)
{
VODCategories vodCategories;
for (int i = 0; i < response.body().getVODCategories().size(); i++) {
//inserting in vod categories
vodCategories = response.body().getVODCategories().get(i);
dbHelper.insertVODCategories(vodCategories);
}
}
else {
// No data returned etc
}
}
else
{
//response.body().getResponse().getMessage() display in toast
//Toast.makeText(getActivity(),response.body().getResponse().getMessage(),Toast.LENGTH_LONG).show();
}
}
else
{
// leave it
}
}
else
{
// Display proper message
}
progressDialog.dismiss();
}
@Override
public void onFailure(Call<VODServiceResponse> call, Throwable t) {
Log.e("Fail", "Failure");
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
//Toast.makeText(getActivity(),"Please Check your Internet Connection ",Toast.LENGTH_LONG).show();
}
});
}
数据库插入方式
public boolean insertVODCategories(VODCategories vd) {
db = this.getWritableDatabase();
db.beginTransaction();
try {
ContentValues initialValues = new ContentValues();
initialValues.put(VODCATEGORIES_COLUMN_VODPARENTCATGORYID, vd.getVODParentCategoryId());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYID, vd.getVODCategoryId());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYNAME, vd.getVODCategoryName());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYTHUMBNAILPATH, vd.getVODCategoryThumbnailPath());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYIMAGEPATH, vd.getVODCategoryImagePath());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYIMAGEPATHLARGE, vd.getVODCategoryImagePathLarge());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYDESCRIPTION, vd.getVODCategoryDescription());
initialValues.put(VODCATEGORIES_COLUMN_VODADDEDDATE, vd.getVODCategoryAddedDate());
db.insert(TABLE_VODCATEGORIES, null, initialValues);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
return true;
}
}
您使用的批处理操作有误。您正在数据库事务中执行单个插入,这使得该事务无用。一个事务的重点是做多个操作。
你可以这样做:
List<VODCategories categories = response.body().getVODCategories();
List<ContentValues> valuesList = new ArrayList<>();
VODCategories vd;
for (int i = 0; i < categories.size(); i++) {
vd = categories.get(i);
ContentValues initialValues = new ContentValues();
initialValues.put(VODCATEGORIES_COLUMN_VODPARENTCATGORYID, vd.getVODParentCategoryId());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYID, vd.getVODCategoryId());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYNAME, vd.getVODCategoryName());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYTHUMBNAILPATH, vd.getVODCategoryThumbnailPath());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYIMAGEPATH, vd.getVODCategoryImagePath());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYIMAGEPATHLARGE, vd.getVODCategoryImagePathLarge());
initialValues.put(VODCATEGORIES_COLUMN_VODCATEGORYDESCRIPTION, vd.getVODCategoryDescription());
initialValues.put(VODCATEGORIES_COLUMN_VODADDEDDATE, vd.getVODCategoryAddedDate());
valuesList.add(initialValues);
}
dbHelper.insertVODCategories(valuesList);
为所有对象创建一个 ContentValues
的列表,然后
public boolean insertVODCategories(List<ContentValues> values) {
db = this.getWritableDatabase();
db.beginTransaction();
try {
for(int i = 0; i < values.size(); i++) {
db.insert(TABLE_VODCATEGORIES, null, values.get(i));
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
return true;
}
}
在单个事务中插入所有这些值,这应该会更快。
同样onResponse
在主线程上执行。您可能希望在后台线程上执行数据库操作,这样就不会阻塞 UI.