Ticker

6/random/ticker-posts

Android SQLite Kullanımı Örneği

Android uygulamalarımızda kalıcı veri saklamak istediğimizde kullandığımız yöntemlerden biri de SQLite veritabanı kullanmaktır. Bu yazımda SQLite kullanarak örnek bir Customer tablosu oluşturmayı ve imajdan tarihe, string'den para verisine kadar çok çeşitli veri tiplerinde nasıl veri kaydedeceğimizi ve okuyacağımızı göreceğiz.

 

Android SQLite Kullanımı Örneği
Android SQLite Kullanımı Örneği

 

Öncelikle Customer.java veri sınıfımızı inceleyelim:

import android.graphics.Bitmap;

import java.math.BigDecimal;
import java.util.Date;
// see muratoksuzer.com
public class Customer {

    private Long id;

    private String code;

    private String name;

    private String surname;

    private Integer price = 0;

    private Bitmap image;

    private String phone;

    private String address;

    private String notes;

    private Date date;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }


    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public String getPriceText() {
        BigDecimal decimal = new BigDecimal(price);
        BigDecimal divided = decimal.divide(new BigDecimal(100));

        return divided.toString();
    }

    public Bitmap getImage() {
        return image;
    }

    public void setImage(Bitmap image) {
        this.image = image;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getNotes() {
        return notes;
    }

    public void setNotes(String notes) {
        this.notes = notes;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}

Para verisi hassas veri olduğundan küsüratlardaki hatayı kaldıramaz. Bu nedenle veriyi saklarken 100 ile çarpıp noktalı sayılardan kurtararak Integer tipinde saklıyoruz. Okurken de 100 ile bölerek okuyoruz. Resim foto verisi için android.graphics.Bitmap sınıfını kullanıyoruz. SQLite veritabanına kaydederken bu nesneyi byte array'ine (byte[])  çevirip kaydedeceğiz. 

Şimdi de Android'de SQLite kullanımında veritabanını oluşturmaktan, gerekirse tabloları güncellemekten sorumlu olan  android.database.sqlite.SQLiteOpenHelper sınıfından türettiğimiz CustomerSQLiteHelper.java yardımcı sınıfımızı inceleyelim.

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * @author moksuzer
 * @see muratoksuzer.com
 */
public class CustomerSQLiteHelper extends SQLiteOpenHelper {

    public static final String TABLE_CUSTOMERS = "customers";
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_CODE = "code";
    public static final String COLUMN_NAME = "name";
    public static final String COLUMN_SURNAME = "surname";
    public static final String COLUMN_PHONE = "phone";
    public static final String COLUMN_ADDRESS = "address";
    public static final String COLUMN_DATE = "zaman";
    public static final String COLUMN_IMAGE = "image";
    public static final String COLUMN_NOTES = "notes";

    // price column gercek fiyatin 100 katini tutuyor. noktali sayilarla ugrasmamak icin
    public static final String COLUMN_FEE = "fee";


    public static final String DATABASE_NAME = "customers.db";
    public static final int DATABASE_VERSION = 1;

    // Database creation sql statement
    private static final String DATABASE_CREATE = "create table "
            + TABLE_CUSTOMERS + "(" + COLUMN_ID
            + " integer primary key autoincrement, "
            + COLUMN_CODE + " text not null, "
            + COLUMN_NAME + " text, "
            + COLUMN_SURNAME + " text, "
            + COLUMN_FEE + " INTEGER ,"
            + COLUMN_IMAGE + " blob, "
            + COLUMN_PHONE + " text ,"
            + COLUMN_ADDRESS + " text ,"
            + COLUMN_DATE + " real ,"
            + COLUMN_NOTES + " text "
            + ");";


    public CustomerSQLiteHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
        database.execSQL(DATABASE_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

Para verisini kaydedeceğimiz kolonun INTEGER, resim kaydedeceğimiz kolonun BLOB, tarih kaydedeceğimiz kolonun REAL veri tipinde olduğunu görüyoruz. Normal metin kaydedeceğimiz kolonların ise TEXT olarak belirlendiğini görüyoruz.

onCreate() metodunda eğer ilk defa çalıştırılıyorsa tabloyu oluşturmak için DATABASE_CREATE sql kodu çalıştırılıyor. Eğer tabloyu sonraki sürümlerde değiştirmek istiyorsak mevcut verileri kaybetmemek için DATABASE_VERSION değerini bir arttırmamız ve onUpgrade() metodunda tabloyu güncelleyecek sql kodunu çalıştırmamız gerekir.

Şimdi de veri tabanı işlemlerini uygulama mantığı işlerinden soyutlamak için kullanacağımız, sadece veri tabanı işlemlerinden sorumlu olan (bakınız Single Responsibility Principle) DAO (data access object) sınıfımız olan CustomerDAO.java sınıfını inceleyelim.

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author moksuzer
 * @see muratoksuzer.com
 */
public class CustomerDAO {

    private SQLiteDatabase database;
    private CustomerSQLiteHelper dbHelper;
    private Context context;

    //imaj gerekmeyen sorgularda bunu kullanacagiz
    private String[] allSimpleColumns = {CustomerSQLiteHelper.COLUMN_ID,
            CustomerSQLiteHelper.COLUMN_CODE,
            CustomerSQLiteHelper.COLUMN_NAME,
            CustomerSQLiteHelper.COLUMN_SURNAME,
            CustomerSQLiteHelper.COLUMN_FEE,
            CustomerSQLiteHelper.COLUMN_PHONE,
            CustomerSQLiteHelper.COLUMN_ADDRESS,
            CustomerSQLiteHelper.COLUMN_DATE,
            CustomerSQLiteHelper.COLUMN_NOTES};

    //imaji da okumak istedigimizde bunu kullanacagiz
    private String[] allColumns = {CustomerSQLiteHelper.COLUMN_ID,
            CustomerSQLiteHelper.COLUMN_CODE,
            CustomerSQLiteHelper.COLUMN_NAME,
            CustomerSQLiteHelper.COLUMN_SURNAME,
            CustomerSQLiteHelper.COLUMN_FEE,
            CustomerSQLiteHelper.COLUMN_IMAGE,
            CustomerSQLiteHelper.COLUMN_PHONE,
            CustomerSQLiteHelper.COLUMN_ADDRESS,
            CustomerSQLiteHelper.COLUMN_DATE,
            CustomerSQLiteHelper.COLUMN_NOTES};


    public CustomerDAO(Context context) {
        dbHelper = new CustomerSQLiteHelper(context);
        this.context = context;
    }

    public void open() throws SQLException {
        database = dbHelper.getWritableDatabase();
    }

    public void close() {
        dbHelper.close();
    }

    public Customer create(Customer customer) {
        ContentValues values = buildContentValuesImageAdded(customer);

        long insertId = database.insert(CustomerSQLiteHelper.TABLE_CUSTOMERS, null,
                values);
        customer.setId(insertId);

        return customer;
    }

    public void delete(Customer customer) {
        database.delete(CustomerSQLiteHelper.TABLE_CUSTOMERS, CustomerSQLiteHelper.COLUMN_ID
                + " = ?", new String[]{Long.toString(customer.getId())});

    }


    public void update(Customer customer) {
        if (customer == null || customer.getId() == null) {
            return;
        }

        ContentValues values = buildContentValuesImageAdded(customer);

        database.update(CustomerSQLiteHelper.TABLE_CUSTOMERS, values, CustomerSQLiteHelper.COLUMN_ID
                + " = ?", new String[]{customer.getId().toString()});

    }


    public void updateExcepImage(Customer customer) {
        if (customer == null || customer.getId() == null) {
            return;
        }

        ContentValues values = buildContentValues(customer);

        database.update(CustomerSQLiteHelper.TABLE_CUSTOMERS, values, CustomerSQLiteHelper.COLUMN_ID
                + " = ?", new String[]{customer.getId().toString()});

    }


    public List<Customer> getAllCustomers() {
        List<Customer> customers = new ArrayList<Customer>();

        Cursor cursor = database.query(CustomerSQLiteHelper.TABLE_CUSTOMERS,
                allSimpleColumns, null, null, null, null, null);

        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            Customer customer = cursorToCustomer(cursor);
            customers.add(customer);
            cursor.moveToNext();
        }
        // make sure to close the cursor
        cursor.close();
        return customers;
    }

    public Bitmap getImage(Long id) {
        if (id == null) {
            return null;
        }

        Cursor cursor = database.query(CustomerSQLiteHelper.TABLE_CUSTOMERS,
                allColumns, CustomerSQLiteHelper.COLUMN_ID
                        + " = ?", new String[]{id.toString()}, null, null, null);

        if (cursor == null) {
            return null;
        }

        Customer customer = null;

        cursor.moveToFirst();
        if (!cursor.isAfterLast()) {
            customer = cursorToCustomerImageRead(cursor);
        }
        cursor.close();

        return customer.getImage();
    }

    public Customer findcustomer(Long id) {
        if (id == null) {
            return null;
        }

        Cursor cursor = database.query(CustomerSQLiteHelper.TABLE_CUSTOMERS,
                allColumns, CustomerSQLiteHelper.COLUMN_ID
                        + " = ?", new String[]{id.toString()}, null, null, null);

        if (cursor == null) {
            return null;
        }

        Customer customer = null;

        cursor.moveToFirst();
        if (!cursor.isAfterLast()) {
            customer = cursorToCustomerImageRead(cursor);
        }

        cursor.close();

        return customer;
    }

    public Customer findCustomerByCode(String code) {
        Cursor cursor = database.query(CustomerSQLiteHelper.TABLE_CUSTOMERS,
                allSimpleColumns, CustomerSQLiteHelper.COLUMN_CODE
                        + " = ?", new String[]{code}, null, null, null);

        if (cursor == null) {
            return null;
        }

        Customer customer = null;

        cursor.moveToFirst();
        if (!cursor.isAfterLast()) {
            customer = cursorToCustomer(cursor);
        }

        cursor.close();

        return customer;
    }

    public Customer findCustomerByCodeAddImage(String code) {
        Cursor cursor = database.query(CustomerSQLiteHelper.TABLE_CUSTOMERS,
                allColumns, CustomerSQLiteHelper.COLUMN_CODE
                        + " = ?", new String[]{code}, null, null, null);

        if (cursor == null) {
            return null;
        }

        Customer customer = null;

        cursor.moveToFirst();
        if (!cursor.isAfterLast()) {
            customer = cursorToCustomerImageRead(cursor);
        }

        cursor.close();

        return customer;
    }


    private ContentValues buildContentValues(Customer customer) {
        ContentValues values = new ContentValues();
        values.put(CustomerSQLiteHelper.COLUMN_CODE, customer.getCode());
        values.put(CustomerSQLiteHelper.COLUMN_NAME, customer.getName());
        values.put(CustomerSQLiteHelper.COLUMN_SURNAME, customer.getSurname());
        values.put(CustomerSQLiteHelper.COLUMN_FEE, customer.getPrice());

        values.put(CustomerSQLiteHelper.COLUMN_PHONE, customer.getPhone());
        values.put(CustomerSQLiteHelper.COLUMN_ADDRESS, customer.getAddress());
        values.put(CustomerSQLiteHelper.COLUMN_NOTES, customer.getNotes());
        values.put(CustomerSQLiteHelper.COLUMN_DATE, customer.getDate() != null ? customer.getDate().getTime():null);

        return values;
    }

    private ContentValues buildContentValuesImageAdded(Customer customer) {
        ContentValues values = buildContentValues(customer);

        Bitmap image = customer.getImage();
        if (image == null) {
            values.put(CustomerSQLiteHelper.COLUMN_IMAGE, new byte[0]);
        } else {
            values.put(CustomerSQLiteHelper.COLUMN_IMAGE, getBytes(image));
        }

        return values;
    }

    private Customer cursorToCustomer(Cursor cursor) {

        Customer customer = new Customer();
        customer.setId(cursor.getLong(0));

        customer.setCode(cursor.getString(cursor.getColumnIndex(CustomerSQLiteHelper.COLUMN_CODE)));
        customer.setName(cursor.getString(cursor.getColumnIndex(CustomerSQLiteHelper.COLUMN_NAME)));
        customer.setSurname(cursor.getString(cursor.getColumnIndex(CustomerSQLiteHelper.COLUMN_SURNAME)));

        customer.setPrice(cursor.getInt(cursor.getColumnIndex(CustomerSQLiteHelper.COLUMN_FEE)));

        customer.setPhone(cursor.getString(cursor.getColumnIndex(CustomerSQLiteHelper.COLUMN_PHONE)));
        customer.setAddress(cursor.getString(cursor.getColumnIndex(CustomerSQLiteHelper.COLUMN_ADDRESS)));

        long time = cursor.getLong(cursor.getColumnIndex(CustomerSQLiteHelper.COLUMN_DATE));

        customer.setDate(new Date(time));

        customer.setNotes(cursor.getString(cursor.getColumnIndex(CustomerSQLiteHelper.COLUMN_NOTES)));

        return customer;
    }

    private Customer cursorToCustomerImageRead(Cursor cursor) {

        Customer customer = cursorToCustomer(cursor);

        byte[] blob = cursor.getBlob(cursor.getColumnIndex(CustomerSQLiteHelper.COLUMN_IMAGE));
        if (blob == null || blob.length == 0) {
            customer.setImage(null);
        } else {
            customer.setImage(getImage(blob));
        }

        return customer;
    }


    public int getCount() {
        String query = " SELECT count(*) from " + CustomerSQLiteHelper.TABLE_CUSTOMERS;

        Cursor mCount = database.rawQuery(query, null);
        mCount.moveToFirst();
        int count = mCount.getInt(0);
        mCount.close();

        return count;
    }

    public static byte[] getBytes(Bitmap bitmap) {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 0, stream);
        return stream.toByteArray();
    }

    // convert from byte array to bitmap
    public static Bitmap getImage(byte[] image) {
        return BitmapFactory.decodeByteArray(image, 0, image.length);
    }
}

Klasik bir CRUD (Create Read Update Delete) sayfasının ihtiyacı olan tüm metodların tanımlı olduğunu görüyoruz. 

  • Yeni bir müşteri kaydı oluşturma
  • id'si verilen bir müşteri verisini okuma
  • Tanımlı tüm müşterileri okuma
  • id'si verilen bir müşteriyi silme veya verilerini güncelleme
  • Customer verisini imaj dosyası verisi ile veya resim verisi olmadan okuma 

yeteneklerini bu şekilde dao sınıfımıza kazandırmış olduk. 

Şimdi de bu DAO sınıfını örnek bir Activity sınıfında nasıl kullanacağımızı görelim.

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
/**
 * @author moksuzer
 * @see muratoksuzer.com
 */
public class ExampleActivity extends AppCompatActivity {

    private CustomerDAO dataSource;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //...
        dataSource = new CustomerDAO(this);
        dataSource.open();
    }

    @Override
    protected void onPause() {
        dataSource.close();
        super.onPause();
    }

    @Override
    protected void onResume() {
        dataSource.open();
        super.onResume();
    }

}

ExampleActivity.java sınıfımızda da görüdğümüz gibi Activity sınıfımızın Android SDK'sından gelen onCreate() ve onResume() metodlarında dataSource nesnemizi open() metodu ile kullanıma hazır hale getirmemiz gerekiyor. onPause() metodunda da fazla sistem kaynağı yememek için close() ile kapatmamız gerekiyor. open() çaprıldıktan sonraki durumlarda dao'da tanımladığımız metodlardan istediğimizi çağırarak uygulama mantığımızı gerçekleştirebiliriz.



Yorum Gönder

0 Yorumlar

Ad Code