Saya sering melihat kode yang melibatkan iterasi atas hasil query database, melakukan sesuatu dengan setiap baris, dan kemudian pindah ke baris berikutnya. Contoh khas adalah sebagai berikut.
Cursor cursor = db.rawQuery(...);
cursor.moveToFirst();
while (cursor.isAfterLast() == false)
{
...
cursor.moveToNext();
}
Cursor cursor = db.rawQuery(...);
for (boolean hasItem = cursor.moveToFirst();
hasItem;
hasItem = cursor.moveToNext()) {
...
}
Cursor cursor = db.rawQuery(...);
if (cursor.moveToFirst()) {
do {
...
} while (cursor.moveToNext());
}
Bagi saya, semua ini sepertinya bertele-tele, masing-masing dengan banyak panggilan ke Cursor
metode. Tentunya harus ada cara yang lebih rapi?
Jawaban:
Cara paling sederhana adalah ini:
Kursor dimulai sebelum baris hasil pertama, jadi pada iterasi pertama ini bergerak ke hasil pertama jika ada . Jika kursor kosong, atau baris terakhir sudah diproses, maka loop keluar dengan rapi.
Tentu saja, jangan lupa untuk menutup kursor setelah Anda selesai melakukannya, lebih disukai dalam
finally
klausa.Jika Anda menargetkan API 19+, Anda dapat menggunakan coba-dengan-sumber daya.
sumber
CursorLoader
, pastikan Anda meneleponcursor.moveToPosition(-1)
sebelum iterasi, karena loader menggunakan kembali kursor ketika orientasi layar berubah. Menghabiskan satu jam melacak masalah ini!Cara berpenampilan terbaik yang saya temukan untuk melalui kursor adalah sebagai berikut:
Jangan lupa untuk menutup kursor sesudahnya
EDIT: Solusi yang diberikan sangat bagus jika Anda perlu mengulangi kursor yang bukan tanggung jawab Anda. Contoh yang baik adalah, jika Anda mengambil kursor sebagai argumen dalam suatu metode, dan Anda perlu memindai kursor untuk nilai yang diberikan, tanpa harus khawatir tentang posisi kursor saat ini.
sumber
Saya hanya ingin menunjukkan alternatif ketiga yang juga berfungsi jika kursor tidak pada posisi awal:
sumber
moveToPosition(-1)
. Jadi kedua jawaban sama-sama ringkas karena keduanya memiliki dua panggilan kursor. Saya pikir jawaban ini hanya mengesampingkan jawaban Borland karena tidak memerlukan angka-1
ajaib.Bagaimana dengan menggunakan foreach loop:
Namun versi CursorUtils saya harus kurang jelek, tetapi secara otomatis menutup kursor:
sumber
Cursor
contoh yang sama di setiap iterasi dari loop.Di bawah ini bisa menjadi cara yang lebih baik:
Kode di atas akan memastikan bahwa ia akan melewati seluruh iterasi dan tidak akan lolos dari iterasi pertama dan terakhir.
sumber
Kode contoh:
sumber
iterator()
juga harus menghitung ulangtoVisit = cursor.getCount();
saya menggunakanclass IterableCursor<T extends Cursor> implements Iterable<T>, Iterator<T> {...
yang menerima kelas yangextends CursorWrapper implements MyInterface
mana MyInterface mendefinisikan getter untuk properti database. Dengan cara ini saya memiliki Iterator berbasis kursor <MyInterface>Solusi Do / While lebih elegan, tetapi jika Anda hanya menggunakan solusi While yang diposting di atas, tanpa moveToPosition (-1) Anda akan kehilangan elemen pertama (setidaknya pada permintaan Kontak).
Saya menyarankan:
sumber
sumber
The kursor adalah Antarmuka yang mewakili
2-dimensional
tabel database apapun.Ketika Anda mencoba untuk mengambil beberapa data menggunakan
SELECT
pernyataan, maka database akan membuat objek CURSOR pertama dan mengembalikan referensi kepada Anda.Pointer dari referensi yang dikembalikan ini menunjuk ke lokasi ke - 0 yang sebelumnya disebut sebagai sebelum lokasi pertama dari Kursor, jadi ketika Anda ingin mengambil data dari kursor, Anda harus memindahkan ke-1 ke catatan ke-1 sehingga kita harus menggunakan moveToFirst
Saat Anda memanggil
moveToFirst()
metode pada kursor, dibutuhkan kursor ke lokasi pertama. Sekarang Anda dapat mengakses data yang ada di catatan 1Cara terbaik untuk melihat:
Kursor kursor
sumber
Awalnya kursor tidak berada pada tampilan baris pertama menggunakan
moveToNext()
Anda dapat mengulangi kursor ketika catatan tidak ada makareturn false
, kecualireturn true
,sumber