มาต่อบทความเรื่องฐานข้อมูลบน Android ด้วย SQLite กันต่อครับ หลังจาก Part 1 นำเสนอ วิธีการใช้งาน SQLite เบื้องต้น การสร้างฐานข้อมูลและการ Query ไปแล้ว บทความนี้จะมาต่อเรื่องการใช้ INSERT, UPDATE, DELETE ครับ
Step 1 : INSERT
ต่อมาเราจะทำหน้า AddFriendActivity
ต่อครับ หน้านี้มีไว้สำหรับกรอกรายละเอียดต่างๆ เพื่อเพิ่มลงฐานข้อมูล เริ่มแรกก็สร้างเลเอาท์ของมันก่อน โดยจะให้มีหน้าตาประมาณนี้้
ตั้งชื่อว่า activity_addfriend.xml
เซฟไว้ใน res/layout/
สำหรับไฟล์ String ใน res/values/strings.xml
เผื่อบางคนขี้เกียจตั้งชื่อเอง
เมื่อได้เลเอาท์แล้ว ต่อมาเราจะมาสร้างเมธอดที่ DBHelper
เพื่อทำการ Insert ลงฐานข้อมูลกัน
เปิด DBHelper
ขึ้นมา เพิ่มเมธอด addFriend(Friend)
ลงไป
เมธอดนี้ต้องการ Model Friend หรือคลาส Friend ที่เราได้สร้างไว้นั่นเอง ภายในเมธอดก็เรียก getWritableDatabase()
เพื่อขอสิทธิ์การเขียนฐานข้อมูล จากนั้นก็ใช้ ContentValues
put ค่า Key, Value โดย Key ก็คือชื่อ Column ต่างๆ ที่ได้ประกาศเป็น static final ไว้ ส่วน Value ก็คือค่าของ firstName, LastName, tel, .. เป็นต้น จะเห็นว่าเราไม่ต้องทำการส่งค่า id ลงไปด้วย เนื่องจาก SQLite จะกำหนดให้ column แรกเป็น _id ให้อัตโนมัติอยู่แล้ว
เมื่อได้เมธอดที่ไว้จัดการฐานข้อมูลแล้ว ต่อมาก็สร้างคลาส Activity ใหม่ชื่อว่า AddFriendActivity
จากนั้นก็ทำการเชื่อม View ต่างๆ กับเลเอาท์ซะ จะได้ประมาณนี้
ลองจินตนาการหน้านี้คือหน้าใส่ข้อมูล จากนั้นกดปุ่ม Add เพื่อบันทึกค่า ฉะนั้น mButtonOK
ก็้ต้อง setOnClickListener()
ให้มันเพื่อเมื่อคลิ๊กแล้ว ก็ให้นำค่าใน EditText
ต่างๆ ไปบันทึกในฐานข้อมูล ก็จะได้โค๊ดประมาณนี้
จากโค๊ดด้านบน ก็ทำการสร้าง new instance ของ DBHelper
ขึ้นมาเพื่อจะเรียกใช้เมธอด addFriend()
จากนั้นจะเห็นได้ว่าใน setOnClickListener()
มีการโชว์ Dialog ขึ้นมาก่อน ว่ายืนยันที่จะบันทึกลงฐานข้อมูลหรือไม่ ถ้าหากยืนยัน ก็จะ get ค่าจาก EditText บันทึกใส่ model Friend จากนั้น ก็ ส่งไปที่ addFriend(friend)
ตรงส่วน mHelper.updateFriend()
ตรงส่วนนี้ยังไม่ต้องสนใจนะครับ ข้ามไปก่อน พอดีว่า หน้าเลเอาท์อันนี้มันจะใช้ด้วยกันสองส่วนคือ ตอนที่เราเพิ่มข้อมูลใหม่เลย กับตอนจะแก้ไขข้อมูล ฉะนั้นเลยต้องมีเงื่อนไข แยกไว้ครับ
หน้า เพิ่มข้อมูลก็เสร็จแล้ว แต่…เดี๋ยวก่อน มีหน้าเพิ่มข้อมูล แต่ว่าเรายังไม่มีปุ่มที่จะกดมาหน้านี้เลย นี่นา?
ตามที่ตั้งไว้ คือปุ่มเพิ่ม จะอยู่บน ActionBar ขวามือบนที่หน้าแรก MainActivity
ครับ ฉะนั้นก็ไปเพิ่ม menu ที่หน้า MainActivity
เพิ่มไฟล์ menu ที่โฟลเดอร์ /res/menu/main.xml
ข้างในประกอบไปด้วยโค๊ดแบบนี้
ต่อมาก็เพิ่มโค๊ดนี้ลงไปที่ MainActivity
เพื่อสร้างปุ่มเมนู และเมื่อคลิ๊กที่ปุ่มเมนู ก็จะทำการไปยัง AddFriendActivity
ครับ
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
อันนี้เอาไว้เพิ่ม Animation เวลาข้าม Activity ครับ คือมีการ fade_in และ fade_out
ทดสอบลองรันโปรแกรมใหม่ กดปุ่ม Add เข้าหน้า AddFriendActivity
และทำการเพิ่มข้อมูลลงไปเลยครับ จะได้หน้าตาประมาณนี้
เมื่ออยู่หน้า AddFriendActivity
จะกดกลับไปหน้า MainActivity
ยังไง นอกจากปุ่ม Back?
ในคลาส AddFriendActivity
ต้องเพิ่ม โค๊ดนี้ที่เมธอด onCreate()
ก่อน setContentView()
จากนั้นทำการ override เมธอดนี้ เพื่อเมื่อกดปุ่ม Back Home ก็สั่ง activity#finish()
และกลับไปหน้า MainActivity
Step 2: READ
ต่อมาเราจะทำการเพิ่มหน้า Detail เวลาที่เราจะดูข้อมูลของเพื่อนคนนั้นๆ เช่น เมื่อเราเลือกรายชื่อเพื่อนจาก ListView ใน MainActivity
ก็จะมาหน้า Detail ฉะนั้น หน้านี้ก็จะออกแบบหน้าตาประมาณนี้
ทำการสร้างไฟล์ acitivity_detail.xml
ที่ res/layout/
เมื่อได้หน้าเลเอาท์แล้ว ต่อมาก็มาจัดการเพิ่มเมธอด สำหรับ Query รายละเอียดเพื่อน ใน DBHelper
กัน จากทีแรก เรามีเมธอด ที่สำหรับ Query รายชื่อทั้งหมดแล้ว แต่ว่าตอนนี้เราจะทำการเพิ่มเมธอด สำหรับ Query เพื่อนเพียงคนเดียว โดยมีเงื่อนไข Where เข้ามาช่วย
เปิดไฟล์ DBHelper
เพิ่มเมธอด getFriend(id)
ลงไป
จะเห็นว่าเมธอดนี้รับค่า id ซึ่งจะไม่ซ้ำกันเลย เพื่อเอาไว้ Query หาข้อมูลที่ id มีค่าเท่านี้นะ ภายในเมธอดก็สั่ง getReadableDatabase()
เพื่อขออนุญาตอ่านค่าฐานข้อมูลเช่นเดิม จากนั้นจะใช้ Cursor
เพื่อทำการ Query ฐานข้อมูล Cursor.getXXXX() นั้นจะเหมือนกับในส่วนตอน Query รายชื่อเพื่อนทั้งหมดเลย แต่ต่างกันที่ SQL Statement จากแต่ก่อน เราเรียก SELECT * FROM friend
โดยไม่มีเงือนไขอะไรเพิ่ม แต่ว่าเมธอดนี้ เราจะใช้ SQLiteDatabase#query
เพื่อทำการ Query แบบกำหนดเงื่อนไข
สำหรับรายละเอียดเชิงลึก เกี่ยวกับ query หรือ rawQuery จะไม่พูดถึงในบทความนี้นะครับ เอาไว้แยกออกไปละกัน มาดูคร่าวๆกันก่อนดีกว่า ว่าแต่ละ parameter ที่ส่งไปนั้นมีอะไรบ้าง
- ตัวแรกเป็น 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 กับเลเอาท์ซะ
สังเกตว่าผมมีการส่ง Bundle
มาด้วย อันนี้จะส่งมาจาก MainActivity
เพื่อจะเอาค่า id ไป Query นั่นเอง เลยประกาศไว้ก่อน จากนั้นก็ใช้ id นี้แหละ ไป Query ก็จะได้ข้อมูลมาใส่ใน TextView
จากนั้นกลับไปที่ MainActivity
ทำการเพิ่มเงื่อนไข เมื่อกดที่ ListView ให้ส่ง Activity มาที่หน้า DetailActivity
เนื่องจาก MainActivity
นั่น extends ListActivity
อยู่ ทำให้เราสามารถ override เมธอดได้เลย ดังนี้
จากโค๊ดไม่มีอะไรมาก ผมแค่ทำการเลือก Friend จากตำแหน่งที่ position ของ ListView จากนั้นก็ทำการ ตัด String เอาแต่ค่า id ส่งไปผ่าน putExtra
เพื่อเอาไว้ Query โดย DetailActivity
ก็ได้ getExtra
ไว้รอแล้ว ตามโค๊ดด้านบน
Step 3: Update
ต่อจะเห็นว่า DetailActivity
ผมยังมีอีก 2 ปุ่ม คือ ปุ่ม Edit และปุ่ม Delete จะเอาไว้สำหรับแก้ไขข้อมูลและลบข้อมูล ในส่วน แก้ไขข้อมูล ก็คือใช้หน้าเดียวกับการเพิ่มข้อมูลเลย แต่จะต่างกันที่แก้ไขข้อมูล จะส่ง id
ไปด้วย ทำให้เรารู้ว่าเราจะแก้ไข id
นี้ ในขณะที่ตอนเพิ่มข้อมูลใหม่ เราไม่มี id
ฉะนั้น mButtonEdit
เพื่อจะเอาไว้แก้ไขข้อมูล หรือก็คือการ update ฐานข้อมูลนั่นเอง โค๊ด ก็จะเป็นแบบนี้
จะเห็นว่าส่งค่าโดยใช้ putExtra()
ไปหลายค่ามาก ฉะนั้น ตรง AddFriendActivity
ก็ต้องไปรับค่า Extra ที่ส่งไปด้วย กลับไปแก้ไขไฟล์ AddFriendActivity
โดยเพิ่มนี้ลงไปที่เมธอด onCreate()
หลัง setContentView()
หากเรากดมาจากหน้า Detail ข้อมูลใน EditText มันก็จะเอาค่า detail มาใส่ ในขณะที่เรากดจากหน้า MainActivity มันก็จะไม่มีค่าอะไร ต้องกรอกใหม่ (คิดว่าน่าจะเห็นความต่างนะครับ) สุดท้ายเอา comment ตรง mButtonOk
ออกซะ
แล้วก็ไปทำการเพิ่มเมธอด updateFriend()
ที่คลาส DBHelper
จะเห็นว่า โครงสร้างมันก็คล้ายๆเดิมละคือมีการเรียก getWritableDatabase()
เพื่อขอการเขียนลงฐานข้อมูล ใช้ ContentValues
และ put ค่าลงฐานข้อมูล โดยใช้ SQLiteDatabase#update
ส่ง argement โดยมีเงื่อนไขคือ id = Friend.getId()
นั่นเอง
ตอนนี้ก็ได้ CREATE, INSERT, UPDATE ไปแล้ว ทดลองรันโปรแกรม กดจาก ListView ไปหน้า Detail กด Edit แก้ไขข้อมูล เป็นอันเรียบร้อย :D
Step 4: DELETE
สุดท้ายการลบข้อมูลนั่นเอง เพิ่มเมธอด deleteFriend()
ที่คลาส DBHelper
ดังนี้
ในส่วนของการ delete ข้อมูลนั้น เราก็ใช้เมธอด SQLiteDatabase#delete()
จากนั้นก็ส่ง argument เป็น ชื่อฐานข้อมูล ชื่อ column ที่ต้องการลบ และเงื่อนไข โดยการกำหนดเงื่อนไขทำได้สองแบบคือ ใส่ไปโต้งๆ เป็น Statement ไปเลย หรืออีกแบบ ใช้เป็นแบบ selector และ selectorArgr แบบที่ comment ไว้นั่นเอง จริงๆตรงส่วน query หรือ insert, update มันก็เลือกได้เหมือนกัน ว่าจะใช้แบบไหน
สุดท้าย ปุ่มที่เราจะทำการลบข้อมูลนั้นอยู่ในหน้า DetailActivity
ตรงปุ่ม mButtonDelete
ก็ setListener()
ให้มันซะ แบบนี้
เวลากด Delete ก็จะได้แบบนี้
สรุป
จบไปละครับ สำหรับบทความ Android SQLite ทั้งสองตอน ต้องบอกเลยว่าใช้เวลาเขียนนานมาก กว่าจะมีเวลาว่างเขียน จริงๆก็ทำโปรเจ็คตัวอย่างเสร็จไปนานแล้วด้วย ตัวอย่างอันนี้เป็นแค่ตัวอย่างคร่าวๆนะครับ ไม่มีการเช็คเงื่อนไขต่างๆ ไม่มีการเช็ค Field ของ EditText ว่าถูกต้องหรือไม่ แค่ให้เห็นภาพการ CRUD ฐานข้อมูลครับ
ในส่วนบทความ อาจจะมีขาดตกบกพร่องไปบ้างนะครับ เพราะผมพยายามนำโค๊ดแต่ละส่วน ค่อยๆ นำมาอธิบาย จากโค๊ดที่มันสมบูรณ์แล้ว ทำให้อาจจะมีบางจุดที่ลืมอธิบาย หรือลืมนำโค๊ดมาใส่ ในบทความด้วย ก็เลยทำอัพโปรเจ็คลง Github เอาไว้ clone กันได้เต็มที่ครับ
เอาไว้ดู ไว้อ้างอิงกันครับ ตัวโปรเจ็คผมเป็น Android Studio นะครับ ถ้าใช้ Eclipse หรือ ADT Bundle แนะนำให้ลง plugin ชื่อว่า Gradle ครับ ไม่งั้นก็ต้องใช้วิธี import ด้วยมือเอา ^^