Android Programlama Ders 39: Query Metodunu Ayrıntılı İnceliyoruz

In Makale, Mobil, Pratik by Victor Cuiumju2 Comments

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

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

population

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:

populmore

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.

sorting

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.

Distinctboolean 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.