การนำเข้าข้อมูลจาก .csv ลงในฐานข้อมูล

สำหรับการใช้ฐานข้อมูลเบื้องต้นให้อ่านจาก [Android Code] SQLite บน Android เบื้องต้น (แอบละเอียด)

สำหรับใครที่ใช้ฐานข้อมูลเป็นภาษาไทย ให้เปลี่ยน Encoding จาก ANSI เป็น UTF-8 เพื่อแก้ปัญหาแสดงภาษาไทยเพี้ยนด้วย [Android Code] แก้ปัญหาภาษาไทยใน CSV แสดงผลเพี้ยน

จากคราวก่อนที่เข้าของบล็อกพล่ามเรื่องฐานข้อมูลแล้ว ทีนี้การสร้างฐานข้อมูลขึ้นมาก็ต้องมีข้อมูลที่จะเอามาเก็บ ซึ่งก็แล้วแต่ว่าข้อมูลนั้นๆจะเอามาจากไหน จะให้ผู้ใช้แอพใส่ข้อมูลแล้วเก็บลงฐานข้อมูลก็ได้ หรือจะพิมใส่เตรียมไว้ก็ได้ (แบบตัวอย่างก่อนหน้า) หรือนำเข้าจากไฟล์ฐานข้อมูลต่างๆ

ซึ่งเจ้าของบล็อกก็จะขอพูดถึงการนำเข้าข้อมูลจากไฟล์ CSV มาเก็บไว้ในฐานข้อมูลของแอพฯกัน ก่อนอื่นเลยเราก็ต้องมีไฟล์ CSV ที่จะเอามานำเข้าก่อน เจ้าของบล็อกก็เลยสร้างขึ้นมาเพื่อใช้เป็นตัวอย่าง โดยมีข้อมูลดังนี้

ไฟล์จะชื่อว่า customerdata.csv จากนั้นก็ให้สร้างโปรเจคขึ้นมาใน Eclipse เลย แล้วเอาไฟล์ customdata.csv ใส่เข้าไปในโฟลเดอร์ assets

ทีนี้ก็ลองอ่านค่าจากไฟล์นี้ก่อนละกัน ให้พิมคำสั่งตามนี้เลย โดยเจ้าของบล็อกจะให้แสดงข้อมูลผ่านหน้าต่าง LogCat

package app.akexorcist.databaseimportcsv; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import android.os.Bundle; import android.util.Log; import android.app.Activity; public class Main extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { BufferedReader br = new BufferedReader( new InputStreamReader(getAssets().open( "customerdata.csv"))); String readLine = null; try { while ((readLine = br.readLine()) != null) { Log.i("Data Input", readLine); } } catch (IOException e) { } } catch (IOException e) { } } }


เริ่มจากที่คลาส BufferReader ก่อนเลยละกัน โดยคลาสที่ว่านี้เป็นคลาสสำหรับอ่านข้อมูลจากไฟล์ ซึ่งเจ้าของบล็อกกำหนดให้อ่านไฟล์ customdata.csv ที่อยู่ในส่วนของ Assets โดยใช้คำสั่ง

getAssets().open("customerdata.csv")


มาเก็บไว้ใน InputStreamReader ก่อน แล้วเอามาเก็บใน BufferReader ต่อเลย แต่จะเห็นว่าเจ้าของบล็อกใช้คำสั่งแค่บรรทัดเดียวสร้าง InputStreamReader แล้วส่งค่าให้ BufferRead เลย ต่อมาก็ทำการสร้างตัวแปร String ขึ้นมาชื่อ readLine เอาไว้เก็บ String ของแต่ละแถว มาแสดงใน Log สำหรับการอ่าน String ในแต่ละแถว ก็จะใช้คำสั่ง

readLine = br.readLine()


เมื่อใช้คำสั่งนี้อีกครั้งจะเป็นการอ่านค่าในแถวต่อไปเรื่อยๆ โดยเช็คว่าค่าที่ได้เป็น null หรือป่าว ถ้าใช่ก็คืออ่านครบแล้ว จากนั้นก็จะแสดงข้อมูลผ่านหน้าต่าง LogCat ด้วยคำสั่ง

Log.i("Data Input", readLine);


และเนื่องจากใช้ while วนรอบไปเรื่อยๆ ก็จะแสดงข้อมูล จากตัวแปร readLine ทุกๆครั้งที่มีการอ่านค่าบรรทัดใหม่จนครบ เมื่อลองทดสอบการทำงาน ก็จะเห็นว่า LogCat มีข้อความแสดงขึ้นมาเมื่อเปิดแอพ

จะเห็นว่าข้อมูลที่ออกมาจะเป็นดังนี้

Name,Job,Age,Gender Akito,Student,20,Male Madeil,Student,19,Female Henry,Engineer,32,Male Densell,Magician,8,Male Elf


ข้อมูลในแต่ละคอลัมน์จะถูกคั่นด้วยเครื่องหมายลูกน้ำ

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

String[] str = readLine.split(",");


ก็จะทำให้ข้อมูลแบ่งออกเป็นสี่คอลัมน์ด้วยกัน ซึ่งในแต่ละช่องก็จะมีข้อมูลดังนี้ (สมมติว่าแถวแรกสุด)

strRow[0] : Name strRow[1] : Job strRow[2] : Age strRow[3] : Gender


และเมื่อแบ่งข้อมูลครบทุกๆแถวแล้วก็จะได้ประมาณนี้

ทีนี้ลองมาสร้างเป็นตัวอย่างจริงๆเลยละกัน ก่อนอื่นก็ต้องสร้างคลาส Database ขึ้นมาก่อน

package app.akexorcist.databaseimportcsv; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; class Database extends SQLiteOpenHelper { private static final String DB_NAME = "My Business Data"; private static final int DB_VERSION = 1; public static final String TABLE_NAME = "Customer"; public static final String COL_NAME = "name"; public static final String COL_JOB = "job"; public static final String COL_AGE = "age"; public static final String COL_GENDER = "gender"; Context context; public Database(Context ctx) { super(ctx, DB_NAME, null, DB_VERSION); context = ctx; } public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + COL_NAME + " TEXT, " + COL_JOB + " TEXT, " + COL_AGE + " INTEGER, " + COL_GENDER + " TEXT);"); try { BufferedReader br = new BufferedReader( new InputStreamReader(context.getAssets().open( "customerdata.csv"))); String readLine = null; readLine = br.readLine(); try { while ((readLine = br.readLine()) != null) { String[] str = readLine.split(","); db.execSQL("INSERT INTO " + TABLE_NAME + " (" + COL_NAME + ", " + COL_JOB + ", " + COL_AGE + ", " + COL_GENDER + ") VALUES ('" + str[0] + "', '" + str[1] + "', " + str[2] + ", '" + str[3] + "');"); } } catch (IOException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } } public void onUpgrade(SQLiteDatabase db, int oldVersion , int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } }


คอลัมน์ของฐานข้อมูลเจ้าของบล็อกจะกำหนดชื่อเป็น name, job, age, gender ตามที่ต้องการไว้ แล้วใช้คำสั่ง

readLine = br.readLine();


ครั้งหนึ่งก่อน เพื่อข้ามแถวแรกไปเพราะเป็นแค่ชื่อตาราง จากนั้นก็จะทำการทยอยแบ่งข้อมูลออกเป็นส่วนๆแล้วเก็บลงในฐานข้อมูล จนครบ

ทีนี้มาที่หน้า Main.java ของเจ้าของบล็อก ก็จะกำหนดให้แสดงฐานข้อมูลที่มีอยู่ผ่าน List View

package app.akexorcist.databaseimportcsv; import java.util.ArrayList; import android.os.Bundle; import android.view.Window; import android.widget.ArrayAdapter; import android.widget.ListView; import android.app.Activity; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; public class Main extends Activity { SQLiteDatabase mDb; Database mHelper; Cursor mCursor; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); ListView listView1 = (ListView)findViewById(R.id.listView1); mHelper = new Database(this); mDb = mHelper.getWritableDatabase(); mHelper.onUpgrade(mDb, 1, 1); mCursor = mDb.rawQuery("SELECT " + Database.COL_NAME + ", " + Database.COL_JOB + ", " + Database.COL_AGE + ", " + Database.COL_GENDER + " FROM " + Database.TABLE_NAME, null); ArrayList<String> dirArray = new ArrayList<String>(); mCursor.moveToFirst(); while ( !mCursor.isAfterLast() ){ dirArray.add("Name : " + mCursor.getString (mCursor.getColumnIndex(Database.COL_NAME)) + "\n" + "Job : " + mCursor.getString(mCursor.getColumnIndex (Database.COL_JOB)) + "\n" + "Age : " + mCursor.getString(mCursor.getColumnIndex (Database.COL_AGE)) + "\n" + "Gender : " + mCursor.getString(mCursor.getColumnIndex (Database.COL_GENDER))); mCursor.moveToNext(); } ArrayAdapter<String> adapterDir = new ArrayAdapter<String>(getApplicationContext() , android.R.layout.simple_list_item_1, dirArray); listView1.setAdapter(adapterDir); } public void onPause() { super.onPause(); mHelper.close(); mDb.close(); } }


และสำหรับ main.xml เจ้าของบล็อกขอใช้เหมือนตัวอย่างที่แล้วละกัน

<?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" android:background="#666666" > <TextView android:id="@+id/textView1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Customer" android:textColor="#222222" android:textSize="40dp" android:gravity="center" android:layout_marginTop="20dp" /> <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="30dp" android:cacheColorHint="#00000000" /> </LinearLayout>


ทีนี้ก็ลองทดสอบแอพฯดู ก็จะเห็นว่าไฟล์ CSV ได้ถูกเก็บลงบนฐานข้อมูลแล้วนำมาแสดงบน List View แล้ว

สำหรับผู้ที่หลงเข้ามาอ่านที่จะเอาไปประยุกต์ใช้ ในตัวอย่างเจ้าของบล็อกใช้ฐานข้อมูลที่มี 4 คอลัมน์ ให้แก้ไขในส่วนของคอลัมน์ให้ตรงกับที่จะใช้ด้วย ทั้งชื่อคอลัมน์และจำนวนคอลัมน์ของข้อมูล