13 Şubat 2018 Salı

Android Dersleri 5 - Sqlite veritabanı kullanımı, Android Sqlite örnek uygulama, SQLiteOpenHelper, SQLiteDatabase


5 - SQLITE

5.1 - First example from my notebook

Photos -> 25. maddedeki     Sqlite örneğini inceleyerek başlayabilirsin.

5.2 -  SQLITE from javatpoint

http://www.javatpoint.com/android-sqlite-tutorial
        SQLite is an open-source relational database i.e. used to perform database operations on android devices such as storing, manipulating or retrieving persistent data from the database. A very powerful, embedded relational database management system. ( SQLite, güçlü ve gömülü bir RDMBS'dir. Açık kaynak kodludur. Android cihazlar'da SQLite default olarak kurulu gelir. Ekstradan herhangi bir şey kurmamıza gerek yoktur. Sqlite kullanarak veritabanı manipulasyon işlemleri yapabiliriz.   )

        SQLite is one way of storing user data. SQLite is a very lightweight database which comes with Android OS. In this tutorial I’ll be discussing how to write classes to handle all SQLite operations.  ( SQLite, lightweight bir veritabanıdır. SQLite, Android işletim sistemi ile birlikte gelir. SQLite veritabanı işlemlerini uygulamak için class'ları nasıl yazacağımızı öğreneceğiz. )

        In this tutorial I am taking an example of storing user contacts in SQLite database. I am using a table called Contacts to store user contacts. This table contains three columns id (INT), name (TEXT), phone_number(TEXT). ( Bu derste, kişi bilgilerini SQLite database'de saklamayı öğreneceğiz.  Contacts isimli bir table'da kişi bilgilerini saklayacağız. Contacts isimli table şu 3 sütunu içeirir :
- id
- name
- phone_number         )

        It is embedded in android by default. So, there is no need to perform any database setup or administration task. ( SQLite, Android işletim sistemiyle otomatik olarak gelir, diğer bir deyişle Android OS'da gömülüdür. Ekstradan herhangi bir şey kurmamıza gerek yoktur.  )

        Data is displayed in the logcat. For displaying data on the spinner or listview, move to the next page.

        SQLiteOpenHelper class provides the functionality to use the SQLite database. ( SQLite veritabanını kullanmak için gerekli functionality'yi SQLiteOpenHelper class'ı sağlar. Dolayısıyla SQLite veritabanını kullanmak için SQLiteOpenHelper class'ını kullanmalıyız. )

SQLiteOpenHelper class


        For performing any database operation, you have to provide the implementation of onCreate() and onUpgrade() methods of SQLiteOpenHelper class. (  )

There are two constructors of SQLiteOpenHelper class. (SQLiteOpenHelper class'ının 2 tane constructor'ı vardır. )
SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) creates an object for creating, opening and managing the database.
SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler)     creates an object for creating, opening and managing the database. It specifies the error handler.

SQLiteOpenHelper class'ının içerdiği method'lardan bazılarını inceleyelim:
public abstract void onCreate(SQLiteDatabase db) : called only once when database is created for the first time. (Veritabanı ilk kez yaratılırken onCreate() method'u çağırılır. )
public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)        called when database needs to be upgraded. ( Veritabanı upgrade edilmesi gerektiği zaman onUpgrade() method'u çağırılır.  )
public synchronized void close()   closes the database object. ( database object'i kapatır. )
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion)     called when database needs to be downgraded. ( Veritabanı downgrade edilmesi gerektiği zaman onDowngrade() method'u çağırılır.  )

SQLiteDatabase class
        Sqlite veritabanındaki gerçekleştirilecek olan create, update, delete, select gibi işlemleri, SQLiteDatabase class'ının içerdiği method'lar yardımıyla gerçekleştiririz. SQLiteDatabase class'ının içerdiği method'lardan bazıları şunlardır :
void execSQL(String sql)      : executes the sql query not select query. ( Bu method'a parametre olarak bir sql query verilir string olarak. execSql() method'u çağırılınca execSql() method'unun aldığı parametredeki sql çalıştırılır. )
long insert(String table, String nullColumnHack, ContentValues values)  :        inserts a record on the database. The table specifies the table name, nullColumnHack doesn't allow completely null values. If second argument is null, android will store null values if values are empty. The third argument specifies the values to be stored. ( Veritabanına bir record(satır) insert etmek için SQLiteDatabase class'ının insert method'u çağırılır. )
int  update(String table, ContentValues values, String whereClause, String[] whereArgs)      bir satırı günceller.
Cursor  query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)  returns a cursor over the resultset( Cursor object return eder).
Example :
MainActivity.java
        Bu derste contactsManager isimli bir veritabanı ve contacts isimli bir table tanımlayacağız. Sonra contacts table'ı üzerinde veritabanı manipulasyonu yapabilecek method'lar implement edeceğiz.
        MainActivity class'ının onStart() method'unda setContentView(R.layout.activity_main.xml) method'unu çağırarak layout'u set ederiz. Sonra DatabaseHandler class'ından yeni bir object yaratırız. db isimli reference variable bu object'e refer eder. DatabaseHandler class'ı, SQLiteOpenHelper class'ını extend eder. Sonra DatabaseHandler class'ının addContact() method'unu çağırırız 4 kere, bu method'a her defasında da farklı Contact object'ler veririz, bu method her çağırıldığında contacts isimli veritabanına bir satır insert edilir. Sonra DatabaseHandler class'ının getAllContacts() method'unu çağırarak contacts isimli veritabanındaki tüm satırları okuruz, elde ederiz, bu method Contact object'leri içeren bir List return eder. Sonra for döngüsünde listedeki tüm elemanların üzerinde gezip bu elemanları yazdırırız.
        Activity'nin menüsünün layout'unu nasıl set ederiz. onCreateOptionsMenu method'unda getMenuInflater().inflate(R.menu.activity_main, menu) method'unu çağırarak.


Contact.java
        contacts isimli table'da 3 tane sütun vardır. Bu table'a karşılık gelen bir class tanımlarız, bu class'ın ismi Contact'dır ve 3 tane variable içerir: _id , _name ve _phone_number .
File: DatabaseHandler.java
        Now, let's create the database handler class that extends SQLiteOpenHelper class and provides the implementation of its methods.
        Activity class'ında veritabanı manipülasyon işlemlerini yapmak için tanımladığımız DatabaseHandler class'ını inceleyelim. DatabaseHandler class'ının içerdiği variable'ları inceleyelim :
- private static final int DATABASE_VERSION = 1;
 - private static final String DATABASE_NAME = "contactsManager"; veritabanı ismi belirtilir.
 - private static final String TABLE_CONTACTS = "contacts"; table ismi belirtilir.
 - private static final String KEY_ID = "id"; table'da kullanılacak bir sütun ismi belirtilir. Bu sütun ismi id'dir. KEY_ID isimli variable tanımlanmış, bu variable'a "id" string değeri assign edilmiştir.
 - private static final String KEY_NAME = "name"; table'da kullanılacak bir sütun ismi belirtilir. Bu sütun ismi name'dir. KEY_NAME isimli variable tanımlanmış, bu variable'a "name" string değeri assign edilmiştir.
 - private static final String KEY_PH_NO = "phone_number"; table'da kullanılacak bir sütun ismi belirtilir. Bu sütun ismi phone_number'dir. KEY_PHONE_NUMBER isimli variable tanımlanmış, bu variable'a " phone_number" string değeri assign edilmiştir.
        DatabaseHandler class'ının constructor'ını doğru implement etmek önemlidir. Bu constructor çalıştırılarak bir object yaratıldığında, ilgili veritabanına bağlanılır:
public DatabaseHandler(Context context)
{
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

        onCreate() method'unu çağırırsak, contactsManager veritabanında contacts isimli table'ı yaratırız.  onCreate() method'unun aldığı parameter'ın SqliteDatabase object olduğunua dikkat et. SqliteDatabase object'in execSQL, insert(), close(), query(),rawQuery() gibi method'larını çağırarak veritabanı manipülasyonu işlemleri yaparız.
public void onCreate(SQLiteDatabase db)
{
        db.execSQL("CREATE TABLE contacts ....");
}

       
         addContact (contact) : This method accepts Contact object as parameter. We need to build ContentValues parameters using Contact object. Once we inserted data in database we need to close the database connection. addContact method'unu çağırırsak, bu method'a argument olara verdiğimiz Contact object'in name ve phone_number bilgilerini elde ederiz ve contacts table'a bir satır insert ederiz. Bunun için önce addContact() method'unda, önce SQLiteDatabase object elde etmeliyiz. Table üzerinde bir değişiklik yapmak istediğimiz için this.getWritableDatabase() diyerek bir SQLiteDatabase object elde ederiz. Sonra ContentValues values = new ContentValues();   diyerek bir ContentValues object elde ederiz. Sonra bu object'in put() method'unu çağırarak table'daki hangi sütuna hangi değeri koymak istediğimizi belirtiriz. Sonra ContentValues object'i insert method'unun 3.parametresine veririz, db.insert(TABLE_CONTACTS, null, values) deriz. insert() method'unun 1.parametresi satır eklemek istediğimiz table'dır. 3.parametresi ise ContentValues object'dir, hangi sütuna hangi değeri koymak istediğimizi belirtir. Veritabanında bir değişiklik yaptığımız için bu method'un sonunda db.close() method'unu çağırarak veritabanı bağlantımızı kapatmalıyız. db'ye satır insert ederken id sütununu belirtmediğimize dikkat edelim. id sütunu primary key olduğu için otomatik olarak belirlenir.
void addContact(Contact contact)
{
        SQLiteDatabase db = this.getWritableDatabase(); 
       
        ContentValues values = new ContentValues(); 
        values.put(KEY_NAME, contact.getName()); // Contact Name 
        values.put(KEY_PH_NO, contact.getPhoneNumber()); // Contact Phone 
         
        db.insert(TABLE_CONTACTS, null, values); 
        db.close(); // Closing database connection 
}

        getContact() : This method will read single contact row. It accepts id as parameter and will return the matched row from the database. Table üzerinde bir değişiklik yapmak istemediğimiz için, sadece veritabanından veri okumak istediğimiz için this.getReadableDatabase() diyerek bir SQLiteDatabase object elde ederiz. SQLiteDatabase object'in query method'unu çağırarak bir select sorgusu çalıştırdığımızı düşünelim. query() method'Unun, 1. parametresi -> select sorgusu atacağımız table'ı belirtir.
2. parametresi -> sorgu sonucunda hangi sütunları almak istediğimizi belirtir. select x,y,z from ...
3. parametresi -> where clause'dur. select ... where KEY_ID + "=?"
4. parametresi -> bir array'dir. Bu array'in elemanları sırasıyla where clause'daki ? soru işaretli kısımlarla replace edilir.
query() method'u ne return eder? Cursor object. Örneğin select sorgusu 10 tane satır return ediyorsa, cursor object'in moveToFirst() method'unu çağırarak ilk satıra refer ederiz. Bir döngü içinde moveToNext() method'unu çağırarak herbir döngüde bir sonraki satıra refer ederiz.
cursor object null ise cursor'ın hiçbir satıra refer etmediğini anlarız. Bu örnekte cursor null ise, select sorgusunun hiçbir satır return etmediğini anlarız.
cursor.getString(0), cursor object'in refer ettiği satırdaki 1.sütundaki değeri return eder.
cursor.getString(1), cursor object'in refer ettiği satırdaki 2.sütundaki değeri return eder.
cursor.getString(2), cursor object'in refer ettiği satırdaki 3.sütundaki değeri return eder.
Bu değerleri kullanarak bir Contact object yaratıp bu object'i return ederiz.
Contact getContact(int id)
{ 
         SQLiteDatabase db = this.getReadableDatabase(); 
         Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,  KEY_NAME, KEY_PH_NO }, KEY_ID + "=?",  new String[] { String.valueOf(id) }, null, null, null, null); 
         if (cursor != null) 
                   cursor.moveToFirst(); 
         Contact contact = new Contact(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2)); 
         return contact;  }<

getAllContacts() : This method will return all contacts from database in array list format of Contact class type. You need to write a for loop to go through each contact.  Contact object'leri tutan bir ArrayList object yaratırız.
this.getWritableDatabase() diyerek bir SQLiteDatabase object elde ederiz. Bu object'i kullanarak veritabanına erişebilriz. Daha önceki örneklerde getWritableDatabase() method'unu veritabanında bir değişiklik yapacağımız case'lerde çağırmıştık, ancak bu case'de veritabanından bilgi okumak için this.getWritableDatabase() diyerek bir SQLiteDatabase object elde ettik.  getWritableDatabase ve getReadableDatabase arasındaki farkı bu dökümanda anlattım.
        Sonra SQLiteDatabase object'in rawQuery() method'unu çağırarak bir select sorgusu çalıştırdığımızı düşünelim. Aynı işi yukarıda query()  method'unu çağırarak yapmıştık. peki query() ve rawQuery() arasındaki fark nedir?
Eğer where sorgusunda ?'li kısım koyup sonra ? kısımla başka bir string'i replace etmek istiyorsak bunun için query() method'Unu kullanmalıyız. Eğer "select * from contacts" gibi bir şey çalıştıracaksak rawQuery() method'unu çağırmalıyız.
public List<Contact> getAllContacts()
{
            List<Contact> contactList = new ArrayList<Contact>(); 
            String selectQuery = "SELECT  * FROM " + TABLE_CONTACTS; 
            SQLiteDatabase db = this.getWritableDatabase(); 
            Cursor cursor = db.rawQuery(selectQuery, null);

            if (cursor.moveToFirst()) { 
                        do {
                                   Contact contact = new Contact(); 
                                   contact.setID(Integer.parseInt(cursor.getString(0))); 
                                   contact.setName(cursor.getString(1)); 
                                   contact.setPhoneNumber(cursor.getString(2));  
                                   contactList.add(contact); 
                        }
                        while (cursor.moveToNext()); 
            }
            return contactList;
}
        updateContact()  : Güncellemek istediğimiz contact object'i, updateContact() method'Una parametre olarak veririz. ContentValues object yaratırız ve güncellemek istediğimiz sütunları ve bu sütunların değerlerini values.put() method'unu çağırarak belirleriz.
db.update() method'unun:
- 1.parametresi : güncellenecek table ismini belirtir.
- 2.parametresi : güncellenecek satırlar ve bu satırların değerlerini belirten ContentValues object.
- 3.parametresi : where clause. KEY_ID + " = ?"
- 4.parametresi : String array. 3.parametredeki soru işaretli yerlere sırasıyla bu array'in elemanları koyulur.
public int updateContact(Contact contact)
{ 
        SQLiteDatabase db = this.getWritableDatabase(); 
  
        ContentValues values = new ContentValues(); 
        values.put(KEY_NAME, contact.getName()); 
        values.put(KEY_PH_NO, contact.getPhoneNumber());
        return db.update(TABLE_CONTACTS, values, KEY_ID + " = ?",  new String[] { String.valueOf(contact.getID()) }); 
}

        Diğer method'ları da benzer şekilde kendin yorumlayabilirsin.

------------------------------------------------

Difference between GetWritableDatabase() and getReadableDatabase()

        They return the same object unless the disk is full or there is some permission error that forces to open the database in read-only mode. The name is a bit confusing though :) ( Disk full değilse ve başka herhangi bir hata oluşmazsa, her iki method'da read/write modda bir veritabanı yaratır veya böyle bir veritabanı zaten varsa bu veritabanını açar. )
        As a rule of thumb you should call these methods outside the UI thread. Both can take a long time to return.
        If you are not going to write the database just use getReadableDatabase as it will contribute to your code clarity and intention. ( Veritabanına yazmayacaksak, kodun daha temiz ve anlaşılır gözükmesi için getReadableDatabase() method'unu çağırmalıyız.  )
( Önemli bir ayrıntı da şudur. getReadableDatabase() method'unda getWritableDatabase() method'u çağırılır. Yani getReadableDatabase() 'nu çağırırsak otomatik olarak getWritableDatabase() method'u da çağırılacaktır, db writable açılamazsa readable açılacaktır.  )
Her iki method da SQLiteDatabase object'e reference return eder.
ContentProvider class'ını extend eden BirthProvider isimli class'ın onCreate() method'unun implementation'ı aşağıdadır inceleyelim.
        public boolean onCreate()
        {
                Context context = getContext();
                dbHelper = new DBHelper(context);
                database = dbHelper.getWritableDatabase();
            if(database == null)
                return false;
            else
                return true;       
        }

5.3 - Sqlite tutorial from official Android Website

https://developer.android.com/training/basics/data-storage/databases.html
Aşağıdaki örneğin source kodunun tamamına şuradan erişebilirsiniz : https://github.com/MoloToha/GeekHubAndroid--Stage-2-/tree/master/src/com/example/rssreader3

Define a Schema and Contract

        One of the main principles of SQL databases is the schema: a formal declaration of how the database is organized. The schema is reflected in the SQL statements that you use to create your database. You may find it helpful to create a companion class, known as a contract class, which explicitly specifies the layout of your schema in a systematic and self-documenting way. ( Şema, bir veritabanının nasıl organize edildiğini ve structure'ını gösterir. )
        A contract class is a container for constants that define names for URIs, tables, and columns. The contract class allows you to use the same constants across all the other classes in the same package. This lets you change a column name in one place and have it propagate throughout your code. ( Veritabanınızdaki table ismi, sütun ismi, URI ismi gibi constant'ları contract class denilen bir container class'da tanımlamak faydalı olacaktır. Bu sayede, aynı package'daki diğer class'larda contract class'da tanımlanan constant'ları kullanırız. Bu sayede sütun ismini değiştirmek istersek sadece contract class'da değiştiririz, diğer tüm class'larda kullandığımız table sütun isimlerini tek tek değiştirmeye gerek kalmaz. )
        A contract class explicitly specifies the schema (how a database and its tables are organized) in a systematic and self-documenting way. It contains constants that define URIs, table names, column names, etc. These constants can be consistently use across all the classes in the same package. So any details/definitions global to the database can be put in the root level whereas for every table an inner class is created listing its columns that can be used by your SQLiteOpenHelper implementation to generate the CREATE and DROP SQL queries. Infact these queries could also reside in the contract classes depending upon your usage.
        If you notice we implemented the BaseColumns interface that makes Postinner class inherit a field called _ID which is the unique primary key field required by some Android classes like the cursor adapters. Hence this can help your DB to work seamlessly with the Android framework. So this basically means that instead of having your ID column’s name as id or something else, it should be _id which is the value of BaseColumns._ID .
        A good way to organize a contract class is to put definitions that are global to your whole database in the root level of the class. Then create an inner class for each table that enumerates its columns. ( Tüm veritabanında global olarak kullanılacak constant'ları, contract class scope'unda tanımlarız. Sonra veritabanındaki herbir table için bir static inner class tanımlarız, herbir table'daki herbir sütun için ilgili inner class içerisinde bir public static final String variable tanımlarız. Bu örnekteki contract class  )
Note: By implementing the BaseColumns interface, your inner class can inherit a primary key field called _ID that some Android classes such as cursor adaptors will expect it to have. It's not required, but this can help your database work harmoniously with the Android framework. ( contract class'ının içerdiği inner static class'larının BaseColumn class'ını extend etmesi zorunlu değildir, ancak extend etmesi inner static class'ımızın Android Framework ile uyumlu çalışmasını sağlar. Çünkü bu, inner class'ımızın _ID isimli bir primary key field'ı miras almasını sağlar, cursor adapter'ler inner class'ın bu field'a sahip olmasını umar.    )
For example, this snippet defines the table name and column names for a single table: ( Örneğin aşağıda contract class'da, bir table ismi ve bu table'daki sütun isimleri tanımlanmıştır.  )

Create a Database Using an SQL Helper

        Once you have defined how your database looks, you should implement methods that create and maintain the database and tables. Here are some typical statements that create and delete a table: ( Veritabanımızın iskeletini yani içerdiği table'ları, table'ların sütunlarını tanımladıktan sonra, table'ların yaratılması için gerekli sql query'leri de yazmalıyız inner static class'lar içerisinde. )
private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
   
"CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
   
FeedEntry._ID + " INTEGER PRIMARY KEY," +
   
FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
   
FeedEntry.COLUMN_NAME_SUBTITLE + TEXT_TYPE + " )";

private static final String SQL_DELETE_ENTRIES =
   
"DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;
        Just like files that you save on the device's internal storage, Android stores your database in private disk space that's associated application. Your data is secure, because by default this area is not accessible to other applications.( Cihazınızın internal storage'ına kaydettiğiniz dosyalar gibi sqlite veritabanı da güvenlidir, veritabanı ilgili uygulama ile ilişkili olan gizli bir disk space'de tutulur. Verileriniz güvenlidir, çünkü bu alana diğer uygulamalardan erişilemez. )
        A useful set of APIs is available in the SQLiteOpenHelper class. When you use this class to obtain references to your database, the system performs the potentially long-running operations of creating and updating the database only when needed and not during app startup. All you need to do is call getWritableDatabase() or getReadableDatabase(). (SQLiteOpenHelper class'ındaki method'ları kullanarak yaptığımız işlemler uzun sürebilir.  Bu işlemler runtime'da gerçekleşir, uygulama başlatılırken değil. Bu işlemleri yapmak için önce getWritableDatabase() or getReadableDatabase() method'larını çağırarak bir SQLiteDatabase object elde ederiz.   )
         Note: Because they can be long-running, be sure that you call getWritableDatabase() or getReadableDatabase() in a background thread, such as with AsyncTask or IntentService. ( Bu işlemler uzun sürebileceği için, getWritableDatabase() or getReadableDatabase() method'larını arka planda çalışan bir thread'de çağırmalıyız, foreground thread'de çağırarak uygulamanın bu işlemin tamamlanmasını beklemek yanlış olur. )
        SQLiteOpenHelper class'ını extend eden bir class yazalım. Bu class'daki şu satıra dikkat edelim: import com.example.rssreader3. FeedReaderContract.FeedEntry;    contract class'ımızda tanımladığımız static inner class olan FeedEntry'yi import ettik. Artık FeedEntry class'ının içerdiği bir variable'a FeedEntry.some_variable diyerek erişebiliriz. onCreate() method'una bakalım: db.execSQL(FeedEntry.SQL_CREATE_ENTRIES); burada execSQL() method'una parametre olarak FeedEntry inner static class'ının SQL_CREATE_ENTRIES isimli string'ini verdik.

To access your database, instantiate your subclass of SQLiteOpenHelper:( Veritabanı üzerinde bir işlem yapmak için önce SQLiteOpenHelper class'ını extend eden FeedReaderDbHelper class'ından bir object yaratırız. Bu object'i bir activity'nin içerisinde yaratıyorsak constructor'a argument olarak this keyword veririz, aksi takdirde getContext() method'unun return ettiği Context object'i vermeliyiz.  )
FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());

Put Information into a Database

        Insert data into the database by passing a ContentValues object to the insert() method: ( Daha önceki örneklerde SQLiteOpenHelper class'ının içerisinde tanımladığımız AddContact() method'u içerisinde this. getWritableDatabase() method'unu çağırmıştık.this keyword'ü SQLiteOpenHelper class'ının scope'u içerisinde çağırıldığı için aslında SQLiteOpenHelper class'ına refer eder. Bu örnekte ise  addContact() diye bir method tanımlamadık SQLiteOpenHelper subclass'ının içerisinde. Dolayısıyla SQLiteOpenHelper class'ından bir object yarattıktan sonra bu object'in getWritableDatabase() method'unu çağırarak bir SQLiteDatabase object elde ederiz, sonra bu object'in insert method'unu çağırırız.   )
// Gets the data repository in write mode
SQLiteDatabase db = mDbHelper.getWritableDatabase();

// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values
.put(FeedEntry.COLUMN_NAME_TITLE, title);
values
.put(FeedEntry.COLUMN_NAME_SUBTITLE, subtitle);

// Insert the new row, returning the primary key value of the new row
long newRowId = db.insert(FeedEntry.TABLE_NAME, null, values);
The first argument for insert() is simply the table name. ( insert() method'unun 1. parametresi insert atılacak table'In ismini belirtir.)

Read Information from a Database


        To read from a database, use the query() method, passing it your selection criteria and desired columns. The method combines elements of insert()and update(), except the column list defines the data you want to fetch, rather than the data to insert. The results of the query are returned to you in aCursor object. ( Daha önceki örneklerde SQLiteOpenHelper class'ının içerisinde tanımladığımız getContact() method'u içerisinde this.getReadableDatabase() method'unu çağırmıştık. this keyword'ü SQLiteOpenHelper class'ının scope'u içerisinde çağırıldığı için aslında SQLiteOpenHelper class'ına refer eder. Bu örnekte ise  getContact() diye bir method tanımlamadık SQLiteOpenHelper subclass'ının içerisinde. Dolayısıyla SQLiteOpenHelper class'ından bir object yarattıktan sonra bu object'in getReadableDatabase() method'unu çağırarak bir SQLiteDatabase object elde ederiz, sonra bu object'in insert method'unu çağırırız. )
        To look at a row in the cursor, use one of the Cursor move methods, which you must always call before you begin reading values. Generally, you should start by calling moveToFirst(), which places the "read position" on the first entry in the results. For each row, you can read a column's value by calling one of the Cursor get methods, such as getString() or getLong(). For each of the get methods, you must pass the index position of the column you desire, which you can get by calling getColumnIndex() or getColumnIndexOrThrow(). For example: ( Yukarıdaki kodda en son db.query() method'unu çağırdık, bu method bir Cursor object return eder. Cursor object'i kullanarak bir sorgudan return eden birden fazla satır üzerinde gezebiliriz. Cursor object'in moveToFirst() method'unu çağırarak okuma pozisyonunu ilk satıra getiririz. Herbir satırı okumak için cursor object'in getString() , getLong() gibi get method'larını çağırabiliriz. get method'larını çağırırken cursor'In refer ettiği satırdaki kaçıncı sütunu okumak istediğimizi de belirtiriz. Aşağıdaki örneği inceleyelim. )
cursor.moveToFirst();
long itemId = cursor.getLong(
    cursor
.getColumnIndexOrThrow(FeedEntry._ID)
);

Delete Information from a Database


        To delete rows from a table, you need to provide selection criteria that identify the rows. The database API provides a mechanism for creating selection criteria that protects against SQL injection. The mechanism divides the selection specification into a selection clause and selection arguments. The clause defines the columns to look at, and also allows you to combine column tests. The arguments are values to test against that are bound into the clause. Because the result isn't handled the same as a regular SQL statement, it is immune to SQL injection. ( delete() method'unun aldığı 2. argument : where clause'dur, ? soru işaretli kısım içerebilir. 3. argument ise bir String array'dir, bu array'in elemanları 2.argument'deki ? soru işaretli kısımlara koyulur sırayla. )
// Define 'where' part of query.
String selection = FeedEntry.COLUMN_NAME_TITLE + " LIKE ?";
// Specify arguments in placeholder order.
String[] selectionArgs = { "MyTitle" };
// Issue SQL statement.
db
.delete(FeedEntry.TABLE_NAME, selection, selectionArgs);

Update a Database

        Updating the table combines the content values syntax of insert() with the where syntax of delete(). ( update() method'unun syntax'ı hem insert() hem de delete() method'unun syntax'ına benzer. )
SQLiteDatabase db = mDbHelper.getReadableDatabase();

// New value for one column
ContentValues values = new ContentValues();
values
.put(FeedEntry.COLUMN_NAME_TITLE, title);

// Which row to update, based on the title
String selection = FeedEntry.COLUMN_NAME_TITLE + " LIKE ?";
String[] selectionArgs = { "MyTitle" };

int count = db.update(
   
FeedReaderDbHelper.FeedEntry.TABLE_NAME,
    values
,
    selection
,
    selectionArgs
);

Other resources :
·         android official site'dakine benzer bir tutorial da şu sitede var. contract class'lardan falan da behsediliyor burada:  http://codetheory.in/working-sqlite-database-crud-operations-android/
·         http://androidessence.com/sqlite-in-android-part-1/
·         https://github.com/androidessence/MovieDatabase/blob/master/app/src/main/java/androidessence/moviedatabase/MovieContract.java

Hiç yorum yok:

Yorum Gönder