Tôi cần thực hiện chèn một vài hàng trong một giao dịch. Tôi có thể làm điều đó với ContentProvider không?Nhiều hàng được chèn với ContentProvider
Trả lời
Ở phía máy khách, ContentResolver
hỗ trợ phương thức bulkInsert()
. Các giao dịch đó sẽ không nhất thiết được xử lý trong một giao dịch duy nhất theo số ContentProvider
, đơn giản vì có thể không có bất kỳ giao dịch nào được thực hiện bởi ContentProvider
.
Như tôi hiểu, nếu nó không phải là o verrriden - nó sẽ chỉ gọi vài phương pháp 'chèn' standrt? – earsonheart
Chính xác. Bạn không có ý tưởng nếu bất kỳ 'ContentProvider' đã cho ghi đè' bulkInsert() ', trừ khi nó là' ContentProvider' của riêng bạn. – CommonsWare
Tôi nghĩ rằng bạn nên đi với ContentProviderOperations, đọc hướng dẫn này http://www.grokkingandroid.com/better-performance-with-contentprovideroperation/ –
Tôi đã thực hiện điều này trong ứng dụng của mình và đây là ý chính của mã mà tôi sử dụng.
Trong nhà cung cấp nội dung của tôi, tôi đã ghi đè phương pháp applyBatch() và đó là một phương pháp rất đơn giản để ghi đè lên:
/**
* Performs the work provided in a single transaction
*/
@Override
public ContentProviderResult[] applyBatch(
ArrayList<ContentProviderOperation> operations) {
ContentProviderResult[] result = new ContentProviderResult[operations
.size()];
int i = 0;
// Opens the database object in "write" mode.
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
// Begin a transaction
db.beginTransaction();
try {
for (ContentProviderOperation operation : operations) {
// Chain the result for back references
result[i++] = operation.apply(this, result, i);
}
db.setTransactionSuccessful();
} catch (OperationApplicationException e) {
Log.d(TAG, "batch failed: " + e.getLocalizedMessage());
} finally {
db.endTransaction();
}
return result;
}
Kết quả được trao cho các hoạt động tiếp theo bởi vì bạn muốn hỗ trợ trở lại tài liệu tham khảo. Khi tôi thực sự muốn thay đổi nội dung trong cơ sở dữ liệu trong đơn giao dịch I vòng lặp này trong nội dung của tôi và làm công cụ như thế này:
operations.add(ContentProviderOperation
.newInsert(
Uri.withAppendedPath(
NotePad.Notes.CONTENT_ID_URI_BASE,
Long.toString(task.dbId)))
.withValues(task.toNotesContentValues(0, listDbId))
.build());
// Now the other table, use back reference to the id the note
// received
noteIdIndex = operations.size() - 1;
operations.add(ContentProviderOperation
.newInsert(NotePad.GTasks.CONTENT_URI)
.withValues(task.toGTasksContentValues(accountName))
.withValueBackReferences(
task.toGTasksBackRefContentValues(noteIdIndex))
.build());
Bạn chỉ cần nhớ để kết thúc bằng cách gọi:
provider.applyBatch(operations);
này sẽ thực hiện công cụ của bạn trong một giao dịch duy nhất và hỗ trợ backreferences nếu bạn cần id từ một chèn trước đó mà không có vấn đề.
Dưới đây là một ví dụ cho bulkInsert:
/**
* Perform bulkInsert with use of transaction
*/
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
int uriType = 0;
int insertCount = 0;
try {
uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = dbHelper.getWritableDatabase();
switch (uriType) {
case MEASUREMENTS:
try {
sqlDB.beginTransaction();
for (ContentValues value : values) {
long id = sqlDB.insert(Tab_Measurements.TABLE_NAME, null, value);
if (id > 0)
insertCount++;
}
sqlDB.setTransactionSuccessful();
} catch (Exception e) {
// Your error handling
} finally {
sqlDB.endTransaction();
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
// getContext().getContentResolver().notifyChange(uri, null);
} catch (Exception e) {
// Your error handling
}
return insertCount;
}
Và trong một cái gì đó mã của bạn như:
/**
* Inserts new measurement information.
*
* @param ArrayList of measurements
* @return number of inserted entries
*/
public static long bulkInsertEntries(ArrayList<Item_Measurement> readings) {
// insert only if data is set correctly
if (readings.size() == 0)
return 0;
long insertCount = 0;
try {
// insert new entries
// ArrayList<ContentValues> valueList = new ArrayList<ContentValues>();
ContentValues[] valueList = new ContentValues[readings.size()];
int i = 0;
for (Item_Measurement reading : readings) {
ContentValues values = new ContentValues();
values.put(COL_TIME_READING, reading.getTimeReading());
// ...
valueList[i++] = values;
}
// returns ID
insertCount = ContentProviderOwn.getAppContext().getContentResolver()
.bulkInsert(ContentProviderOwn.MEASUREMENTS_URI_BASE, valueList);
} catch (Exception e) {
// Your error handling
}
return insertCount;
}
Làm thế nào điều này tốt hơn so với gọi một chèn thường xuyên trong một vòng lặp từ mảng ban đầu của dữ liệu? Có lợi ích hiệu suất trong việc sử dụng BulkInsert không? –
@AndrewS bulkInsert() là tốt hơn nhiều về các hoạt động lớn. Chỉ cần hoàn thành tối ưu hóa trong ứng dụng của tôi: applyBatch() với 2000 hoạt động trên một số bảng mất 2000 ms, 10 bulkInsert mất 100 ms. –
tôi cũng sử dụng thay thế chế độ cho chèn hàng - db.insertWithOnConflict (EVENT_TABLE_NAME, null , giá trị, SQLiteDatabase.CONFLICT_REPLACE); nó sẽ thoát khỏi xung đột nếu kỷ lục là tồn tại đã
Trong DatabaseHelper thêm INDEX UNIQUE
public class DataProvider extends ContentProvider {
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db){
db.execSQL(CREATE_EVENT_TABLE);
db.execSQL("CREATE UNIQUE INDEX event_idx ON " + EVENT_TABLE_NAME + " (" + EventTable.EVENT_ID + ")");
// ...
...
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
Log.i(TAG, "bulkInsert");
if (values.length == 0)
return 0;
int insertCount = 0;
try {
switch (uriMatcher.match(uri)) {
case EVENT_LIST:
try {
db.beginTransaction();
for (ContentValues value : values) {
long id = db.insertWithOnConflict(EVENT_TABLE_NAME, null, value, SQLiteDatabase.CONFLICT_REPLACE);
if (id > 0)
insertCount++;
}
db.setTransactionSuccessful();
} catch (Exception e) {
// Your error handling
} finally {
db.endTransaction();
}
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
} catch (Exception e) {
Log.i(TAG, "Exception : " + e);
}
return insertCount;
}
Và gọi bulkInsert như thế này:
ContentValues[] cvArr = new ContentValues[eventList.size()];
long insertCount = 0;
int i = 0;
for (Event event : eventList) {
ContentValues cv = new ContentValues();
cv.put(DataProvider.EventTable.EVENT_ID, event.id);
cv.put(DataProvider.EventTable.SENSOR_ID, event.sensor_id);
cv.put(DataProvider.EventTable.TIMESTAMP, event.time);
cvArr[i++] = cv;
}
// returns ID
insertCount = context.getContentResolver()
.bulkInsert(DataProvider.CONTENT_EVENT_LIST, cvArr);
- 1. SQL Chèn nhiều hàng
- 2. chèn nhiều hàng bằng một lệnh chèn
- 3. Chèn nhiều hàng trong SQLite
- 4. Chèn nhiều hàng vào Oracle
- 5. Chèn nhiều hàng trong mysql
- 6. Lấy id được chèn cuối cùng cho nhiều hàng
- 7. Khi nào ContentProvider thực sự được tạo?
- 8. Codeigniter Chèn nhiều hàng trong SQL
- 9. SQL Chèn dữ liệu một hàng hoặc nhiều hàng?
- 10. Chèn nhiều hàng bằng cách sử dụng JdbcTemplate
- 11. Chèn nhiều hàng vào bảng trong SQL Server
- 12. Chèn hàng loạt chậm cho bảng có nhiều chỉ mục
- 13. SQL - Chèn nhiều giá trị hàng vào một cột đơn
- 14. Chèn nhiều hàng trong SQL Server từ Java
- 15. Chèn cùng một giá trị cố định vào nhiều hàng
- 16. Chèn nhiều bản ghi với một câu lệnh chèn
- 17. Làm cách nào để nhận ID của nhiều hàng được chèn vào trong MySQL?
- 18. Android ContentProvider with Services
- 19. zend framework nhận id chèn cuối cùng của chèn nhiều hàng bằng cách thực hiện
- 20. Tắt thông báo trên URI ContentProvider
- 21. Làm cách nào để chèn nhiều hàng vào oracle với giá trị chuỗi?
- 22. Oracle SQL - chèn nhiều hàng vào một bảng với một câu lệnh?
- 23. SQL Server 2005: Chèn nhiều hàng với một truy vấn đơn
- 24. Chèn nhiều SQL hiệu quả
- 25. Cách lấy giá trị từ hàng được chèn cuối cùng?
- 26. Chèn vào nhiều lựa chọn
- 27. tại sao chèn một hàng duy nhất nhanh hơn x lần so với chèn x hàng cùng một lúc
- 28. Nhiều hàng với một INSERT duy nhất trong SQLServer 2008
- 29. Khung thực thể lệnh chèn hàng
- 30. contentprovider Android không trở Phone.NUMBER
Câu hỏi là không rõ ràng .. dù sao đi nữa, bạn có thể xem tại đây http : //developer.android.com/guide/topics/providers/content-providers.html#modifying –
http://stackoverflow.com/questions/5596354/insertion-of-thousands-of-contact-entries-using-applybatch -is-slow – Selvin