ตัวอย่างการใช้งาน SQLite บน Android ตอนที่ 2


Update! สำหรับคนที่สงสัยเกี่ยวกับการเรียกดูข้อมูลในฐานข้อมูลได้อย่างไร ติดตามอ่านบทความได้ที่นี่ครับ วิธีการเรียกดูข้อมูล SQLite จาก Emulator

มาต่อบทความเรื่องฐานข้อมูลบน Android ด้วย SQLite กันต่อครับ หลังจาก Part 1 นำเสนอ วิธีการใช้งาน SQLite เบื้องต้น การสร้างฐานข้อมูลและการ Query ไปแล้ว บทความนี้จะมาต่อเรื่องการใช้ INSERT, UPDATE, DELETE ครับ

Step 1 : INSERT

ต่อมาเราจะทำหน้า AddFriendActivity ต่อครับ หน้านี้มีไว้สำหรับกรอกรายละเอียดต่างๆ เพื่อเพิ่มลงฐานข้อมูล เริ่มแรกก็สร้างเลเอาท์ของมันก่อน โดยจะให้มีหน้าตาประมาณนี้้

Add Friend Layout

ตั้งชื่อว่า activity_addfriend.xml เซฟไว้ใน res/layout/

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_margin="20dp" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/friend_first_name"
                android:textSize="24sp" />

            <EditText
                android:id="@+id/add_first_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="24sp"
                android:singleLine="true" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/friend_last_name"
                android:textSize="24sp" />

            <EditText
                android:id="@+id/add_last_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="24sp"
                android:singleLine="true" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/friend_tel"
                android:textSize="24sp" />

            <EditText
                android:id="@+id/add_tel"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="24sp"
                android:singleLine="true" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/friend_email"
                android:textSize="24sp" />

            <EditText
                android:id="@+id/add_email"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="24sp"
                android:singleLine="true" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/friend_description"
                android:textSize="24sp" />

            <EditText
                android:id="@+id/add_description"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="24sp"
                android:singleLine="false" />

        </LinearLayout>

        <Button
            android:id="@+id/button_submit"
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:padding="15dp"

            android:layout_marginTop="20dp"
            android:text="@android:string/ok" />

    </LinearLayout>

</LinearLayout>

สำหรับไฟล์ String ใน res/values/strings.xml เผื่อบางคนขี้เกียจตั้งชื่อเอง

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">AhoySQLite</string>

    <string name="friend_first_name">FirstName</string>
    <string name="friend_last_name">LastName</string>
    <string name="friend_tel">Tel</string>
    <string name="friend_email">Email</string>
    <string name="friend_description">Description</string>

    <string name="action_delete">Delete</string>
    <string name="action_edit">Edit</string>
    <string name="action_add">Add</string>

    <string name="alert_title">Delete this friend?</string>
    <string name="alert_message">Are you sure to delete this friend?</string>

    <string name="add_data_title">Add this friend?</string>
    <string name="add_data_message">Are you sure to add this friend?</string>

</resources>

เมื่อได้เลเอาท์แล้ว ต่อมาเราจะมาสร้างเมธอดที่ DBHelper เพื่อทำการ Insert ลงฐานข้อมูลกัน

เปิด DBHelper ขึ้นมา เพิ่มเมธอด addFriend(Friend) ลงไป

public void addFriend(Friend friend) {
    sqLiteDatabase = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    //values.put(Friend.Column.ID, friend.getId());
    values.put(Friend.Column.FIRST_NAME, friend.getFirstName());
    values.put(Friend.Column.LAST_NAME, friend.getLastName());
    values.put(Friend.Column.TEL, friend.getTel());
    values.put(Friend.Column.EMAIL, friend.getEmail());
    values.put(Friend.Column.DESCRIPTION, friend.getDescription());

    sqLiteDatabase.insert(Friend.TABLE, null, values);

    sqLiteDatabase.close();
}

เมธอดนี้ต้องการ Model Friend หรือคลาส Friend ที่เราได้สร้างไว้นั่นเอง ภายในเมธอดก็เรียก getWritableDatabase() เพื่อขอสิทธิ์การเขียนฐานข้อมูล จากนั้นก็ใช้ ContentValues put ค่า Key, Value โดย Key ก็คือชื่อ Column ต่างๆ ที่ได้ประกาศเป็น static final ไว้ ส่วน Value ก็คือค่าของ firstName, LastName, tel, .. เป็นต้น จะเห็นว่าเราไม่ต้องทำการส่งค่า id ลงไปด้วย เนื่องจาก SQLite จะกำหนดให้ column แรกเป็น _id ให้อัตโนมัติอยู่แล้ว

เมื่อได้เมธอดที่ไว้จัดการฐานข้อมูลแล้ว ต่อมาก็สร้างคลาส Activity ใหม่ชื่อว่า AddFriendActivity จากนั้นก็ทำการเชื่อม View ต่างๆ กับเลเอาท์ซะ จะได้ประมาณนี้

package com.devahoy.sample.ahoysqlite;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.devahoy.sample.ahoysqlite.model.Friend;
import com.devahoy.sample.ahoysqlite.utils.DBHelper;


public class AddFriendActivity extends Activity {

    private EditText mFirstName;
    private EditText mLastName;
    private EditText mTel;
    private EditText mEmail;
    private EditText mDescription;
    private Button mButtonOK;

    private DBHelper mHelper;

    private int ID = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_addfriend);

        mFirstName = (EditText) findViewById(R.id.add_first_name);
        mLastName = (EditText) findViewById(R.id.add_last_name);
        mTel = (EditText) findViewById(R.id.add_tel);
        mEmail = (EditText) findViewById(R.id.add_email);
        mDescription = (EditText) findViewById(R.id.add_description);
        mButtonOK = (Button) findViewById(R.id.button_submit);

    }

}

ลองจินตนาการหน้านี้คือหน้าใส่ข้อมูล จากนั้นกดปุ่ม Add เพื่อบันทึกค่า ฉะนั้น mButtonOK ก็้ต้อง setOnClickListener() ให้มันเพื่อเมื่อคลิ๊กแล้ว ก็ให้นำค่าใน EditText ต่างๆ ไปบันทึกในฐานข้อมูล ก็จะได้โค๊ดประมาณนี้

mHelper = new DBHelper(this);

mButtonOK.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        AlertDialog.Builder builder =
                new AlertDialog.Builder(AddFriendActivity.this);
        builder.setTitle(getString(R.string.add_data_title));
        builder.setMessage(getString(R.string.add_data_message));

        builder.setPositiveButton(getString(android.R.string.ok),
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Friend friend = new Friend();
                        friend.setFirstName(mFirstName.getText().toString());
                        friend.setLastName(mLastName.getText().toString());
                        friend.setTel(mTel.getText().toString());
                        friend.setEmail(mEmail.getText().toString());
                        friend.setDescription(mDescription.getText().toString());

                        if (ID == -1) {
                            mHelper.addFriend(friend);
                        } else {
                            friend.setId(ID);
                            //mHelper.updateFriend(friend);
                        }
                        finish();
                    }
                });

        builder.setNegativeButton(getString(android.R.string.cancel),
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });


        builder.show();
    }
});

จากโค๊ดด้านบน ก็ทำการสร้าง new instance ของ DBHelper ขึ้นมาเพื่อจะเรียกใช้เมธอด addFriend() จากนั้นจะเห็นได้ว่าใน setOnClickListener() มีการโชว์ Dialog ขึ้นมาก่อน ว่ายืนยันที่จะบันทึกลงฐานข้อมูลหรือไม่ ถ้าหากยืนยัน ก็จะ get ค่าจาก EditText บันทึกใส่ model Friend จากนั้น ก็ ส่งไปที่ addFriend(friend)

ตรงส่วน mHelper.updateFriend() ตรงส่วนนี้ยังไม่ต้องสนใจนะครับ ข้ามไปก่อน พอดีว่า หน้าเลเอาท์อันนี้มันจะใช้ด้วยกันสองส่วนคือ ตอนที่เราเพิ่มข้อมูลใหม่เลย กับตอนจะแก้ไขข้อมูล ฉะนั้นเลยต้องมีเงื่อนไข แยกไว้ครับ

หน้า เพิ่มข้อมูลก็เสร็จแล้ว แต่…เดี๋ยวก่อน มีหน้าเพิ่มข้อมูล แต่ว่าเรายังไม่มีปุ่มที่จะกดมาหน้านี้เลย นี่นา?

ตามที่ตั้งไว้ คือปุ่มเพิ่ม จะอยู่บน ActionBar ขวามือบนที่หน้าแรก MainActivity ครับ ฉะนั้นก็ไปเพิ่ม menu ที่หน้า MainActivity

เพิ่มไฟล์ menu ที่โฟลเดอร์ /res/menu/main.xml ข้างในประกอบไปด้วยโค๊ดแบบนี้

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_add"
        android:orderInCategory="100"
        android:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add"/>
</menu>

ต่อมาก็เพิ่มโค๊ดนี้ลงไปที่ MainActivity เพื่อสร้างปุ่มเมนู และเมื่อคลิ๊กที่ปุ่มเมนู ก็จะทำการไปยัง AddFriendActivity ครับ

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_add) {
        Intent addFriend = new Intent(this, AddFriendActivity.class);

        startActivity(addFriend);
        overridePendingTransition(android.R.anim.fade_in,
                android.R.anim.fade_out);
    }
    return super.onOptionsItemSelected(item);
}

overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); อันนี้เอาไว้เพิ่ม Animation เวลาข้าม Activity ครับ คือมีการ fadein และ fadeout

ทดสอบลองรันโปรแกรมใหม่ กดปุ่ม Add เข้าหน้า AddFriendActivity และทำการเพิ่มข้อมูลลงไปเลยครับ จะได้หน้าตาประมาณนี้

Add Friend

Add Friend2

เมื่ออยู่หน้า AddFriendActivity จะกดกลับไปหน้า MainActivity ยังไง นอกจากปุ่ม Back?

ในคลาส AddFriendActivity ต้องเพิ่ม โค๊ดนี้ที่เมธอด onCreate() ก่อน setContentView()

getActionBar().setDisplayHomeAsUpEnabled(true);

จากนั้นทำการ override เมธอดนี้ เพื่อเมื่อกดปุ่ม Back Home ก็สั่ง activity#finish() และกลับไปหน้า MainActivity

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    finish();
    overridePendingTransition(android.R.anim.fade_in,
            android.R.anim.fade_out);

    return super.onOptionsItemSelected(item);
}

Step 2: READ

ต่อมาเราจะทำการเพิ่มหน้า Detail เวลาที่เราจะดูข้อมูลของเพื่อนคนนั้นๆ เช่น เมื่อเราเลือกรายชื่อเพื่อนจาก ListView ใน MainActivity ก็จะมาหน้า Detail ฉะนั้น หน้านี้ก็จะออกแบบหน้าตาประมาณนี้

Detail Layout

ทำการสร้างไฟล์ acitivity_detail.xml ที่ res/layout/

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"

    android:padding="20dp">


    <TextView
        android:id="@+id/detail_first_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/friend_first_name"
        android:textSize="24sp"/>

    <TextView
        android:id="@+id/detail_last_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="@string/friend_last_name"
        android:textSize="24sp"/>

    <TextView
        android:id="@+id/detail_tel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="@string/friend_tel"
        android:textSize="24sp"/>


    <TextView
        android:id="@+id/detail_email"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="@string/friend_email"
        android:textSize="24sp"/>


    <TextView
        android:id="@+id/detail_description"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="@string/friend_description"
        android:textSize="24sp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="20dp">

        <Button
            android:id="@+id/button_edit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/action_edit"
            />

        <Button
            android:id="@+id/button_delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/action_delete"
            />

    </LinearLayout>


</LinearLayout>

เมื่อได้หน้าเลเอาท์แล้ว ต่อมาก็มาจัดการเพิ่มเมธอด สำหรับ Query รายละเอียดเพื่อน ใน DBHelper กัน จากทีแรก เรามีเมธอด ที่สำหรับ Query รายชื่อทั้งหมดแล้ว แต่ว่าตอนนี้เราจะทำการเพิ่มเมธอด สำหรับ Query เพื่อนเพียงคนเดียว โดยมีเงื่อนไข Where เข้ามาช่วย

เปิดไฟล์ DBHelper เพิ่มเมธอด getFriend(id) ลงไป

public Friend getFriend(String id) {

    sqLiteDatabase = this.getReadableDatabase();

    Cursor cursor = sqLiteDatabase.query( Friend.TABLE,
            null,
            Friend.Column.ID + " = ? ",
            new String[] { id },
            null,
            null,
            null,
            null);


    if (cursor != null) {
        cursor.moveToFirst();
    }

    Friend friend = new Friend();

    friend.setId((int) cursor.getLong(0));
    friend.setFirstName(cursor.getString(1));
    friend.setLastName(cursor.getString(2));
    friend.setTel(cursor.getString(3));
    friend.setEmail(cursor.getString(4));
    friend.setDescription(cursor.getString(5));

    return friend;
}

จะเห็นว่าเมธอดนี้รับค่า id ซึ่งจะไม่ซ้ำกันเลย เพื่อเอาไว้ Query หาข้อมูลที่ id มีค่าเท่านี้นะ ภายในเมธอดก็สั่ง getReadableDatabase() เพื่อขออนุญาตอ่านค่าฐานข้อมูลเช่นเดิม จากนั้นจะใช้ Cursor เพื่อทำการ Query ฐานข้อมูล Cursor.getXXXX() นั้นจะเหมือนกับในส่วนตอน Query รายชื่อเพื่อนทั้งหมดเลย แต่ต่างกันที่ SQL Statement จากแต่ก่อน เราเรียก SELECT * FROM friend โดยไม่มีเงือนไขอะไรเพิ่ม แต่ว่าเมธอดนี้ เราจะใช้ SQLiteDatabase#query เพื่อทำการ Query แบบกำหนดเงื่อนไข

สำหรับรายละเอียดเชิงลึก เกี่ยวกับ query หรือ rawQuery จะไม่พูดถึงในบทความนี้นะครับ เอาไว้แยกออกไปละกัน มาดูคร่าวๆกันก่อนดีกว่า ว่าแต่ละ parameter ที่ส่งไปนั้นมีอะไรบ้าง

sqLiteDatabase.query( Friend.TABLE,
            null,
            COL_ID + " = ? ",
            new String[] { id },
            null,
            null,
            null,
            null);
  • ตัวแรกเป็น Friend.TABLE คือ ชื่อ Table ที่เราจะ query นั่นเอง
  • ตัวสอง null คือ column ที่เราจะ select ใส่ null เพื่อต้องการทั้งหมด (เหมือนกับ SELECT *)
  • ตัวสาม คือ เงื่อนไขที่เราจะใส่ไป (เหมือนกับ where id = ?)
  • ตัวสี่ คือ ค่า argument ที่มันจะเอาไปใส่แทนเครื่องหมาย ? อันข้างบน หากค่านี้เป็น 10 มันก็จะเท่ากับ (where id = 10)
  • ตัว 5 - 8 เป็น groupBy, Having, orderBy และก็ Limit ตามลำดับ ซึ่งไม่ต้องการใช้ ก็ใส่ null ไป

หวังว่าจะเข้าใจบ้างนะครับ ไว้เดี๋ยวผมหาโอกาสทำบทความเรื่องนี้โดยเฉพาะทีหลังครับ :D

เมื่อได้เมธอดสำหรับ Query เพื่อนจาก id แล้ว ก็ไปสร้างคลาส Detail ซะ ตั้้งชื่อว่า DetailActivity จากนั้นก็เชื่อม View กับเลเอาท์ซะ

public class DetailActivity extends Activity {
    DBHelper mHelper;

    private TextView mFirstName;
    private TextView mLastName;
    private TextView mTel;
    private TextView mEmail;
    private TextView mDescription;
    private String id = "";

    private Button mButtonEdit;
    private Button mButtonDelete;

    private Friend mFriend;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getActionBar().setDisplayHomeAsUpEnabled(true);

        mHelper = new DBHelper(this);

        Bundle bundle  = getIntent().getExtras();

        if (bundle != null) {
            id = bundle.getString(Friend.Column.ID);
        }

        setContentView(R.layout.acitivity_detail);

        mFirstName = (TextView) findViewById(R.id.detail_first_name);
        mLastName = (TextView) findViewById(R.id.detail_last_name);
        mTel = (TextView) findViewById(R.id.detail_tel);
        mEmail = (TextView) findViewById(R.id.detail_email);
        mDescription = (TextView) findViewById(R.id.detail_description);
        mButtonDelete = (Button) findViewById(R.id.button_delete);
        mButtonEdit = (Button) findViewById(R.id.button_edit);
    }

}

สังเกตว่าผมมีการส่ง Bundle มาด้วย อันนี้จะส่งมาจาก MainActivity เพื่อจะเอาค่า id ไป Query นั่นเอง เลยประกาศไว้ก่อน จากนั้นก็ใช้ id นี้แหละ ไป Query ก็จะได้ข้อมูลมาใส่ใน TextView

mFriend = mHelper.getFriend(id);

mFirstName.setText(mFriend.getFirstName());
mLastName.setText(mFriend.getLastName());
mTel.setText(mFriend.getTel());
mEmail.setText(mFriend.getEmail());
mDescription.setText(mFriend.getDescription());

จากนั้นกลับไปที่ MainActivity ทำการเพิ่มเงื่อนไข เมื่อกดที่ ListView ให้ส่ง Activity มาที่หน้า DetailActivity เนื่องจาก MainActivity นั่น extends ListActivity อยู่ ทำให้เราสามารถ override เมธอดได้เลย ดังนี้

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);

    Intent detail = new Intent(this, DetailActivity.class);
    String listName = friends.get(position);
    int index = listName.indexOf(" ");
    String columnId = listName.substring(0, index);

    detail.putExtra(Friend.Column.ID, columnId);
    startActivity(detail);
    overridePendingTransition(android.R.anim.fade_in,
            android.R.anim.fade_out);

}

จากโค๊ดไม่มีอะไรมาก ผมแค่ทำการเลือก Friend จากตำแหน่งที่ position ของ ListView จากนั้นก็ทำการ ตัด String เอาแต่ค่า id ส่งไปผ่าน putExtra เพื่อเอาไว้ Query โดย DetailActivity ก็ได้ getExtra ไว้รอแล้ว ตามโค๊ดด้านบน

Step 3: Update

ต่อจะเห็นว่า DetailActivity ผมยังมีอีก 2 ปุ่ม คือ ปุ่ม Edit และปุ่ม Delete จะเอาไว้สำหรับแก้ไขข้อมูลและลบข้อมูล ในส่วน แก้ไขข้อมูล ก็คือใช้หน้าเดียวกับการเพิ่มข้อมูลเลย แต่จะต่างกันที่แก้ไขข้อมูล จะส่ง id ไปด้วย ทำให้เรารู้ว่าเราจะแก้ไข id นี้ ในขณะที่ตอนเพิ่มข้อมูลใหม่ เราไม่มี id

ฉะนั้น mButtonEdit เพื่อจะเอาไว้แก้ไขข้อมูล หรือก็คือการ update ฐานข้อมูลนั่นเอง โค๊ด ก็จะเป็นแบบนี้

mButtonEdit.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent updateIntent = new Intent(DetailActivity.this,
                AddFriendActivity.class);

        updateIntent.putExtra(Friend.Column.ID, mFriend.getId());
        updateIntent.putExtra(Friend.Column.FIRST_NAME, mFriend.getFirstName());
        updateIntent.putExtra(Friend.Column.LAST_NAME, mFriend.getLastName());
        updateIntent.putExtra(Friend.Column.TEL, mFriend.getTel());
        updateIntent.putExtra(Friend.Column.EMAIL, mFriend.getEmail());
        updateIntent.putExtra(Friend.Column.DESCRIPTION, mFriend.getDescription());

        startActivity(updateIntent);
        overridePendingTransition(android.R.anim.fade_in,
                android.R.anim.fade_out);
    }
});

จะเห็นว่าส่งค่าโดยใช้ putExtra() ไปหลายค่ามาก ฉะนั้น ตรง AddFriendActivity ก็ต้องไปรับค่า Extra ที่ส่งไปด้วย กลับไปแก้ไขไฟล์ AddFriendActivity โดยเพิ่มนี้ลงไปที่เมธอด onCreate() หลัง setContentView()

Bundle bundle = getIntent().getExtras();

if (bundle != null) {
    ID = bundle.getInt(Friend.Column.ID);
    String firstName = bundle.getString(Friend.Column.FIRST_NAME);
    String lastName = bundle.getString(Friend.Column.LAST_NAME);
    String tel = bundle.getString(Friend.Column.TEL);
    String email = bundle.getString(Friend.Column.EMAIL);
    String description = bundle.getString(Friend.Column.DESCRIPTION);

    mFirstName.setText(firstName);
    mLastName.setText(lastName);
    mTel.setText(tel);
    mEmail.setText(email);
    mDescription.setText(description);
}

หากเรากดมาจากหน้า Detail ข้อมูลใน EditText มันก็จะเอาค่า detail มาใส่ ในขณะที่เรากดจากหน้า MainActivity มันก็จะไม่มีค่าอะไร ต้องกรอกใหม่ (คิดว่าน่าจะเห็นความต่างนะครับ) สุดท้ายเอา comment ตรง mButtonOk ออกซะ

mHelper.updateFriend(friend);

แล้วก็ไปทำการเพิ่มเมธอด updateFriend() ที่คลาส DBHelper

public void updateFriend(Friend friend) {

    sqLiteDatabase  = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(Friend.Column.ID, friend.getId());
    values.put(Friend.Column.FIRST_NAME, friend.getFirstName());
    values.put(Friend.Column.LAST_NAME, friend.getLastName());
    values.put(Friend.Column.EMAIL, friend.getEmail());
    values.put(Friend.Column.DESCRIPTION, friend.getDescription());

    int row = sqLiteDatabase.update(Friend.TABLE,
            values,
            Friend.Column.ID + " = ? ",
            new String[] { String.valueOf(friend.getId()) });

    sqLiteDatabase.close();
}

จะเห็นว่า โครงสร้างมันก็คล้ายๆเดิมละคือมีการเรียก getWritableDatabase() เพื่อขอการเขียนลงฐานข้อมูล ใช้ ContentValues และ put ค่าลงฐานข้อมูล โดยใช้ SQLiteDatabase#update ส่ง argement โดยมีเงื่อนไขคือ id = Friend.getId() นั่นเอง

ตอนนี้ก็ได้ CREATE, INSERT, UPDATE ไปแล้ว ทดลองรันโปรแกรม กดจาก ListView ไปหน้า Detail กด Edit แก้ไขข้อมูล เป็นอันเรียบร้อย :D

Detail Activity

Edit

Step 4: DELETE

สุดท้ายการลบข้อมูลนั่นเอง เพิ่มเมธอด deleteFriend() ที่คลาส DBHelper ดังนี้

public void deleteFriend(String id) {

    sqLiteDatabase = this.getWritableDatabase();

    /*sqLiteDatabase.delete(Friend.TABLE, Friend.Column.ID + " = ? ",
            new String[] { String.valueOf(friend.getId()) });*/
    sqLiteDatabase.delete(Friend.TABLE, Friend.Column.ID + " = " + id, null);

    sqLiteDatabase.close();
}

ในส่วนของการ delete ข้อมูลนั้น เราก็ใช้เมธอด SQLiteDatabase#delete() จากนั้นก็ส่ง argument เป็น ชื่อฐานข้อมูล ชื่อ column ที่ต้องการลบ และเงื่อนไข โดยการกำหนดเงื่อนไขทำได้สองแบบคือ ใส่ไปโต้งๆ เป็น Statement ไปเลย หรืออีกแบบ ใช้เป็นแบบ selector และ selectorArgr แบบที่ comment ไว้นั่นเอง จริงๆตรงส่วน query หรือ insert, update มันก็เลือกได้เหมือนกัน ว่าจะใช้แบบไหน

สุดท้าย ปุ่มที่เราจะทำการลบข้อมูลนั้นอยู่ในหน้า DetailActivity ตรงปุ่ม mButtonDelete ก็ setListener() ให้มันซะ แบบนี้

mButtonDelete.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        AlertDialog.Builder builder =
                new AlertDialog.Builder(DetailActivity.this);
        builder.setTitle(getString(R.string.alert_title));
        builder.setMessage(getString(R.string.alert_message));

        builder.setPositiveButton(getString(android.R.string.ok),
                new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                mHelper.deleteFriend(id);

                Toast.makeText(getApplication(),
                        "Deleted", Toast.LENGTH_LONG).show();
                finish();
            }
        });

        builder.setNegativeButton(getString(android.R.string.cancel), null);

        builder.show();

    }
});

เวลากด Delete ก็จะได้แบบนี้

Delete

สรุป

จบไปละครับ สำหรับบทความ Android SQLite ทั้งสองตอน ต้องบอกเลยว่าใช้เวลาเขียนนานมาก กว่าจะมีเวลาว่างเขียน จริงๆก็ทำโปรเจ็คตัวอย่างเสร็จไปนานแล้วด้วย ตัวอย่างอันนี้เป็นแค่ตัวอย่างคร่าวๆนะครับ ไม่มีการเช็คเงื่อนไขต่างๆ ไม่มีการเช็ค Field ของ EditText ว่าถูกต้องหรือไม่ แค่ให้เห็นภาพการ CRUD ฐานข้อมูลครับ

ในส่วนบทความ อาจจะมีขาดตกบกพร่องไปบ้างนะครับ เพราะผมพยายามนำโค๊ดแต่ละส่วน ค่อยๆ นำมาอธิบาย จากโค๊ดที่มันสมบูรณ์แล้ว ทำให้อาจจะมีบางจุดที่ลืมอธิบาย หรือลืมนำโค๊ดมาใส่ ในบทความด้วย ก็เลยทำอัพโปรเจ็คลง Github เอาไว้ clone กันได้เต็มที่ครับ

Source Code

เอาไว้ดู ไว้อ้างอิงกันครับ ตัวโปรเจ็คผมเป็น Android Studio นะครับ ถ้าใช้ Eclipse หรือ ADT Bundle แนะนำให้ลง plugin ชื่อว่า Gradle ครับ ไม่งั้นก็ต้องใช้วิธี import ด้วยมือเอา ^^

Chai

Chai Phonbopit : Developer แห่งหนึ่ง • ผู้ชายธรรมดาๆ ที่ชื่นชอบ Node.js, JavaScript และ Open Source มีงานอดิเรกเป็น Acoustic Guitar และ Football

บทความล่าสุด