Android Programlama Ders 39’da query metodunu kullanarak sıralama, gruplama ve koşul koyma öğreneceğiz.
Geçen derslerimizde tablodan kayıtları okumak için query (Sorgulama) metodu kullanıyorduk. Giriş parametresi olarak sadece tablonun ismi kullanıyorduk ve sonuç olarak tüm kayıtları alıyorduk. Query metodunda başka parametreler de mevcut:
columns – almak istediğimiz alanların listesi
selection –WHERE koşul satırı
selectionArgs – selection için argümanların dizisi. Selection için “?” işareti kullanabiliriz. Soru işareti yerine değerler atanacak.
groupBy – gruplama
having – metotlar için koşul
orderBy – sıralama
Bu parametrelerin ne işe yaradığını daha iyi anlamak için bir örnek proje oluşturalım. Projemiz bir ülkeler rehberi olacak. On tane ülke kullanacağız. Veri tabanına ülkelerin ismini, nüfusunu ve bölgesini kaydedeceğiz.
Ugulamamızda aşağıda verdiğim işlevleri gerçekleştireceğiz:
– tüm kayıtların ekrana çıkarılması
– (SUM, MIN, MAX, COUNT) metotlarının değerinin görüntülenmesi
– belirtilen rakamdan daha büyük nüfusu olan ülkeler listesinin görüntülenmesi
– ülkelerin bölgelere göre gruplanması
– belirtilen rakamdan daha büyük nüfusu olan bölgeler listesinin görüntülenmesi
– isim, nüfus ya da bölgeye göre ülkelerin sıralanması
Tüm sonuçları bildirime (Log) yazdıracağız.
Projeyi oluşturalım:
- Project name: P0039_SQLiteQuery
- Build Target: Android 4.2
- Application name: SQLiteQuery
- Package name: tr.example.sqlitequery
- Create Activity: MainActivity
Main.xml’i açalım ve ekranı oluşturalım:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp" android:gravity="center_horizontal" android:text="Catalog of countries" android:textSize="14sp" > </TextView> <Button android:id="@+id/btnAll" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="All recordings" > </Button> <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp"> <Button android:id="@+id/btnFunc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Function" > </Button> <EditText android:id="@+id/etFunc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1"> <requestFocus> </requestFocus> </EditText> </LinearLayout> <LinearLayout android:id="@+id/linearLayout2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp"> <Button android:id="@+id/btnPeople" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Population >" > </Button> <EditText android:id="@+id/etPeople" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:inputType="number"> </EditText> </LinearLayout> <Button android:id="@+id/btnGroup" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="Population by region" > </Button> <LinearLayout android:id="@+id/linearLayout4" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp"> <Button android:id="@+id/btnHaving" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Population by region >" > </Button> <EditText android:id="@+id/etRegionPeople" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:inputType="number"> </EditText> </LinearLayout> <LinearLayout android:id="@+id/linearLayout3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp"> <Button android:id="@+id/btnSort" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Sorting" > </Button> <RadioGroup android:id="@+id/rgSort" android:layout_width="wrap_content" android:layout_height="wrap_content"> <RadioButton android:id="@+id/rName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="Name" > </RadioButton> <RadioButton android:id="@+id/rPeople" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Population" > </RadioButton> <RadioButton android:id="@+id/rRegion" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Region" > </RadioButton> </RadioGroup> </LinearLayout> </LinearLayout>
Altı tane buton, altı tane metod ve giriş alanları içeriyor. Sıralama için RadioGroup kullanacağız.
MainActivity.java oluşturalım:
import android.app.Activity; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.RadioGroup; public class MainActivity extends Activity implements OnClickListener { final String LOG_TAG = "myLogs"; String name[] = { "China", "USA", "Brazil", "Russia", "Japan", "Germany", "Egypt", "Italy", "France", "Canada" }; int people[] = { 1400, 311, 195, 142, 128, 82, 80, 60, 66, 35 }; String region[] = { "Asia","America","America","Europe","Asia","Europe","Africa", "Europe","Europe","America"}; Button btnAll, btnFunc, btnPeople, btnSort, btnGroup, btnHaving; EditText etFunc, etPeople, etRegionPeople; RadioGroup rgSort; DBHelper dbHelper; SQLiteDatabase db; /** Called when the activity is first created. */ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnAll = (Button) findViewById(R.id.btnAll); btnAll.setOnClickListener(this); btnFunc = (Button) findViewById(R.id.btnFunc); btnFunc.setOnClickListener(this); btnPeople = (Button) findViewById(R.id.btnPeople); btnPeople.setOnClickListener(this); btnSort = (Button) findViewById(R.id.btnSort); btnSort.setOnClickListener(this); btnGroup = (Button) findViewById(R.id.btnGroup); btnGroup.setOnClickListener(this); btnHaving = (Button) findViewById(R.id.btnHaving); btnHaving.setOnClickListener(this); etFunc = (EditText) findViewById(R.id.etFunc); etPeople = (EditText) findViewById(R.id.etPeople); etRegionPeople = (EditText) findViewById(R.id.etRegionPeople); rgSort = (RadioGroup) findViewById(R.id.rgSort); dbHelper = new DBHelper(this); db = dbHelper.getWritableDatabase(); Cursor c = db.query("mytable", null, null, null, null, null, null); if (c.getCount() == 0) { ContentValues cv = new ContentValues(); // tabloyu dolduruyoruz for (int i = 0; i < 10; i++) { cv.put("name", name[i]); cv.put("people", people[i]); cv.put("region", region[i]); Log.d(LOG_TAG, "id = " + db.insert("mytable", null, cv)); } } c.close(); dbHelper.close(); // btnAll butonuna basiyoruz onClick(btnAll); } public void onClick(View v) { // veri tabanina baglaniyoruz db = dbHelper.getWritableDatabase(); // ekrandan bilgileri String sFunc = etFunc.getText().toString(); String sPeople = etPeople.getText().toString(); String sRegionPeople = etRegionPeople.getText().toString(); // query icin degiskenler String[] columns = null; String selection = null; String[] selectionArgs = null; String groupBy = null; String having = null; String orderBy = null; Cursor c = null; // basilan butonu belirliyoruz switch (v.getId()) { case R.id.btnAll: Log.d(LOG_TAG, "--- All records ---"); c = db.query("mytable", null, null, null, null, null, null); break; // fonksiyon case R.id.btnFunc: Log.d(LOG_TAG, "--- Function " + sFunc + " ---"); columns = new String[] { sFunc }; c = db.query("mytable", columns, null, null, null, null, null); break; //Population more than case R.id.btnPeople: Log.d(LOG_TAG, "---Population more than " + sPeople + " ---"); selection = "people > ?"; selectionArgs = new String[] { sPeople }; c = db.query("mytable", null, selection, selectionArgs, null, null, null); break; // Population by region case R.id.btnGroup: Log.d(LOG_TAG, "--- Population by region ---"); columns = new String[] { "region", "sum(people) as people" }; groupBy = "region"; c = db.query("mytable", columns, null, null, groupBy, null, null); break; // Population by region more than case R.id.btnHaving: Log.d(LOG_TAG, "--- Population by region more than " + sRegionPeople + " ---"); columns = new String[] { "region", "sum(people) as people" }; groupBy = "region"; having = "sum(people) > " + sRegionPeople; c = db.query("mytable", columns, null, null, groupBy, having, null); break; // Sorting case R.id.btnSort: // Sorting by name switch (rgSort.getCheckedRadioButtonId()) { case R.id.rName: Log.d(LOG_TAG, "--- Sorting by name---"); orderBy = "name"; break; // population case R.id.rPeople: Log.d(LOG_TAG, "--- Sorting by population ---"); orderBy = "people"; break; // region case R.id.rRegion: Log.d(LOG_TAG, "--- Sorting by region ---"); orderBy = "region"; break; } c = db.query("mytable", null, null, null, null, null, orderBy); break; } if (c != null) { if (c.moveToFirst()) { String str; do { str = ""; for (String cn : c.getColumnNames()) { str = str.concat(cn + " = " + c.getString(c.getColumnIndex(cn)) + "; "); } Log.d(LOG_TAG, str); } while (c.moveToNext()); } c.close(); } else Log.d(LOG_TAG, "Cursor is null"); dbHelper.close(); } class DBHelper extends SQLiteOpenHelper { public DBHelper(Context context) { super(context, "myDB", null, 1); } public void onCreate(SQLiteDatabase db) { Log.d(LOG_TAG, "--- onCreate database ---"); // tabloyu olusturuyoruz db.execSQL("create table mytable (" + "id integer primary key autoincrement," + "name text," + "people integer," + "region text" + ");"); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } }
Giriş alanlara giren değerlerin kontrolü kodda yok çünkü kodu şişirmek istemiyoruz.
Kodda üç tane (Name,people,region) veri dizisi mevcuttur. Bu dizilere göre tabloyu dolduracağız.
onCreate metodunda ekranın nesnelerini belirliyoruz ve işleticiye bağlıyoruz. Veri tabanı yönetmek için dbHelper nesneyi oluşturuyoruz. Sonra veri tabanına bağlanıyoruz ve veri tabanıyla çalışmak için db nesneyi kullanıyoruz. Veri tabanında kayıtları olup olmadığını kontrol ediyoruz, eğer kayıtlar mevcut değilse tabloyu dolduruyoruz ve butona (btnAll=All recordings) basılması emülasyonu yapıyoruz. Emülasyonun amacı bildirime tüm listeyi çıkartmak.
onClick metodunda veri tabanına bağlıyoruz ve ekrandan değerleri okuyup değişkenlere yazdırıyoruz. Sonraki aşamada query (Sorgu) kullanacağımız değişkenleri ve kürsörü belirtiyoruz.Ve basılan butonu buluyoruz.
btnAll – tüm listeyi çıkartıyoruz. Aynı işlemi geçen derste kullandık.
btnFunc – SQL sorguların sonuçlarını bildirime yazdırmak için kullanılıyor. Columns – tablodan istediğimiz alanları içiriyor. SQL’de Select kelimeden genellikle gelen alanlar. String[] –satırların dizisi. etFunc query için giriş alanı.
btnPeople – belirtilen rakamdan daha büyük nüfusu olan ülkeler listesi görüntülemek için kullanıyoruz. Şartı koymak için selection kullanıyoruz. Selection bir argümanı (‘’?’’) kullanıyor. Argümanın değerini selectionArgs’a atıyoruz. Attığımız diğer sPeople eşit etPeople (giriş alanı). Sonraki aşamada query çalıştırıyoruz.
btnGroup – bölgelere göre gruplama ve nüfus sayısının gösterilmesi. Sütunları belirtmek için columns kullanıyoruz. Sütunlarda bölgeleri ve nüfusu göstereceğiz. Bölgelere göre gruplamayı yapmak için groupBy kullanıyoruz. Ve query (Sorgulama) çalıştırıyoruz.
btnHaving – belirtilen rakamdan daha büyük nüfusu olan bölgeler listesi görüntüleme. Gruplamaya benziyor ama having kullanarak şartı ekliyoruz.
btnSort – ülke sıralama. İlk aşamada hangi RadioButton seçilmiş belirlememiz gerekiyor. Sonuca göre orderBy’a sıralanacak alanı belirtiyoruz. Ve query çalıştırıyoruz.
Yukarıdaki metodlarda son aşamada query çalıştırıyoruz. Query kullanarak kürsör (Cursor) klasının nesneyi alıyoruz. Sonra nesnenin olup olmadığını ve içinde kayıtları mevcut (moveToFirst) kontrole geçiyoruz. Kontrol başarılı sonucu verdiği zaman do … while (c.moveToNext()) döngüye (Loop) geçiyoruz. Her kayıt için getColumnNames metodu kullanarak alanların isimlerini tarıyoruz ve her alanın numarasını alıyoruz. Bu bilgileri kullanarak getString metodu sonuç olarak bize verileri gönderiyor. Alanların listesini str değişkene yazdırıyoruz. Ve str’te var olan verileri bildirimi kullanarak ekrana çıkarıyoruz. Son aşamada close metodu kullanarak veritabanıyla bağlantıyı kapatıyoruz.
Kaydedelim ve uygulamayı çalıştıralım.
Bildirimlere bakalım:
— All records—
id = 1; name = China; people = 1400; region = Asia;
id = 2; name = ASA; people = 311; region = America;
id = 3; name = Brazil; people = 195; region =America;
id = 4; name = Russia; people = 142; region = Europe;
id = 5; name = Japan; people = 128; region = Asia;
id = 6; name = Germany; people = 82; region = Europe;
id = 7; name = Еgypt; people = 80; region = Africa;
id = 8; name = Italy; people = 60; region = Europe;
id = 9; name = France; people = 66; region = Europe;
id = 10; name = Canada; people = 35; region = America;
Tablo kayıtlarla dolu olduğunu görüyoruz. Çalışmayı başlayabiliriz.
Bir SQL fonksiyonu çalıştırmaya deneyelim. Mesela kayıtların sayısı öğrenelim:
Function butonuna basalım. Bildirime bakalım:
— Function count(*) as Count —
Count = 10;
Doğru tabloda kayıtların sayısı ona eşit.
Şimdi 100 mln fazla nüfusu olan ülkeleri gösterelim
Bildirime bakalım:
— Population more than 100 —
id = 1; name = China; people = 1400; region = Asia;
id = 2; name = USA; people = 311; region = Аmerica;
id = 3; name = Brazil; people = 195; region = Аmerica;
id = 4; name = Russia; people = 142; region = Еurope;
id = 5; name = Japon; people = 128; region = Аsia;
Bölgeye göre ülkeleri sıralalım ve nüfusu gösterelim. Population by region butonuna basıyoruz.
Bildirim:
— Population by region —
region = Asia; people = 1528;
region = America; people = 541;
region = Africa; people = 80;
region = Europe; people = 350;
Şimdi 500 mln insan fazla bölgeleri gösterelim:
Bildirim:
— Population by region more than 500 —
region = Asia; people = 1528;
region = America; people = 541;
Şimdi sıralama nasıl çalıştığına bakalım.
Bildirim:
— Sorting by population —
id = 10; name = Canada; people = 35; region = America;
id = 8; name = Italy; people = 60; region = Europe;
id = 9; name = France; people = 66; region = Europe;
id = 7; name = Egypt; people = 80; region = Africa;
id = 6; name = Germany; people = 82; region = Europe;
id = 5; name = Japon; people = 128; region = Asia;
id = 4; name = Russia; people = 142; region = Europe;
id = 3; name = Brazil; people = 195; region = America;
id = 2; name = USA; people = 311; region = America;
id = 1; name = China; people = 1400; region = Asia;
Tüm metotlar problemsiz çalışıyor.
Ders Sonu Notları:
Bugünkü derste query’ye ait parametrelerin özellikleri inceledik. Bunun dışında query’de daha iki parametre limit ve distinct olabilir.
Limit – [offset], rows formata belirleniyor. Amacı belirli sütunları göstermektir. Mesela eğer limit eşit 5 ise sorgulama bize ilk beş kaydı gösterecek. Eğer limit eşit “3,5” ise sorgulama ilk dört kayıttan sonra gelen beş kaydı gösterecektir.
Distinct – boolean parametre tekrarlanan kayıtları siliniyor. Yanlış (false) veya doğru (true) durumlarda olabilir.
Gelecek derslerimizde birden fazla tablodan kayıtları okumayı ve rawQuery kullanmayı öğreneceğiz.