Android : เชื่อมต่อฐานข้อมูล Mysql บนเซิฟเวอร์
|สวัสดีครับ บทความนี้ผมจะมาอธิบายตัวอย่างซึ้งเป็นที่นิยม (จริงๆก็มีบทความเรื่องนี้อยู่มากแล้วหละ) และ บ่อยครั้งเราต้องนำไปใช้งาน นั้นคือการเชื่อมต่อฐานข้อมูล Mysql บนเซิฟเวอร์ของเราผ่านแอนดรอยด์แอพพลิเคชั่น ก่อนที่เราจะมาดูโค้ดตัวอย่างกันผมจะอธิบายหลักการทำงานคร่าวๆของตัวอย่างให้ผู้อ่านได้เข้าใจก่อนจากหัวข้อข้างล่างครับ
!! บทความนี้เหมาะกับผู้ที่ต้องการเก็บข้อมูลลงบนเซิฟเวอร์ ไม่ใช่บนอุปกรณ์แอนดรอยด์ หรือ การ์ดต่างๆ
!! ควรมีความรู้เรื่องฐานข้อมูล Mysql ก่อนนะครับ
อธิบายการทำงานคร่าวๆ
รูปที่ 1 แสดงการเข้าถึงฐานข้อมูล Mysql โดยแอนดรอยด์แอพพลิเคชั่น
จากรูปที่ 1 เราแบ่งการทำงานเป็น 2 ฝั่งคือ แอนดรอยด์ และ เซิฟเวอร์ โดยการทำงานมีขั้นตอนดังนี้
1. แอนดอยด์ (Mysql Connector) สั่งให้ php ทำงาน
2. php ทำการเชื่อมต่อและหาข้อมูลจาก Mysql มาแสดงอยู่ในรูปของ json
3. แอนดอยด์อ่าน json จาก php และนำมาแสดง
!! จะเห็นว่าฝั่งแอนดอยด์ทำหน้าที่แค่สั่งและอ่านข้อมูล ส่วนการเชื่อมต่อและค้นหาข้อมูลนั้นทำโดย php
เอาหล่ะเมื่อเราทราบการทำงานคร่าวๆของตัวอย่างแล้วต่อไป ก็ทำการนำโค้ดตัวอย่างมาทำความเข้าใจกันก่อน
โค้ดตัวอย่าง
สามารถ ดาวน์โหลดโปรเจ็คตัวอย่างได้ที่ -> MysqlExample เมื่อดาวน์โหลดแล้วให้สร้างฐานข้อมูลใน Mysql ตามด้านล่างนะครับ
!! โดยตัวอย่างนี้จำเป็นต้องสร้างฐานข้อมูล Mysql ขึ้นมาเอง และ แก้ไขข้อมูลของเซิฟเวอร์และฐานข้อมูลในไฟล์ .php เป็นของผู้อ่านเองด้วยครับ ซึ้งแสดงว่าโหลดเสร็จยังใช้งานไม่ได้ก่อนนะ
อธิบายฐานข้อมูล
ในตัวอย่างนี้ให้ทำการสร้างฐานข้อมูล และตาราง 1 ตารางชื่อว่า member โดยมีโครงสร้างของตารางตามที่แสดงใน รูปที่ 2 และเพิ่มข้อมูลตัวอย่างลงไปในตารางตาม รูปที่ 3
รูปที่ 2 แสดงรายละเอียดตาราง member
รูปที่ 3 ตัวอย่างข้อมูลในตาราง member
อธิบายโค้ดตัวอย่าง
php_get_data.php
ไฟล์นี้ทำหน้าในการเชื่อมต่อฐานข้อมูล Mysql ที่เราสร้างขึ้นโดยจะไป select หรือค้นหาข้อมูลทั้งหมดในตาราง member
!! ไฟล์นี้อยู่ในเซิฟเวอร์นะครับ หรือ locahost
!! ในไฟล์นี้ผู้อ่านต้องทำการเปลี่ยน รายละเอียดในการเชื่อมต่อฐานข้อมูลเป็นของตัวเองในส่วนที่ผมไฮไลท์สีแดงไว้
1:<?php
2: header("content-type:text/javascript;charset=utf-8");
3: $con=mysql_connect('hostname','mysql_username','mysql_password')or die(mysql_error());
4: mysql_select_db('mysql_db_name')or die(mysql_error());
5: mysql_query("SET NAMES UTF8");
6: $sql="SELECT * FROM member";
7: $res=mysql_query($sql);
8: while($row=mysql_fetch_assoc($res)){
9: $output[]=$row;
10: }
11: print(json_encode($output));
12: mysql_close();
13:?>
ซึ้งผลลัพธ์ที่ได้จากการทำงานของ php_get_data.php จะแสดงในรูปของ json ตามรูปที่ 4
รูปที่ 4 ผลลัพธ์ที่ php แสดงผลในรูปแบบ json
MySqlConnection.java
ไฟล์นี้เป็นส่วนสำคัญของตัวอย่างนี้เลยครับ ซึ้งผมจะแยกอธิบายโค้ดเป็น 3 ส่วน เริ่มจากส่วนบนสุดก่อนเลยนะ ตรงนี้จะเป็นส่วนที่ส่ง httppost ไปยังไฟล์ php_get_data.php ผู้อ่านสามารถแก้ url ในจุดที่ผมไฮไลท์สีแดงไว้ และ คอมเม้นท์ด้านหลังคือตัวอย่างครับ
!! หากไม่สามารถเชื่อมต่อไปยัง url ได้ logcat จะแสดงว่า “Error in http connection” .. แสดงว่า url ผิดหรืออินเตอร์เน็ตไม่สามารถเชื่อมต่อกับ url ได้
try {
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
/* Set to Http post*/
/* End set Value*/
HttpClient httpclient = new DefaultHttpClient();
/* Set URL*/
HttpPost httppost = new HttpPost("your url"); // https://10.0.2.2/php_get_data.php
/* End Set URL*/
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,"UTF-8"));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.d("log_err", "Error in http connection " + e.toString());
return list;
}
ส่วนที่ 2 จะทำการอ่านผลลัพธ์ของ php_get_data.php จากรูปที่ 4 มาเก็บไว้เป็น string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"UTF-8"));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
is.close();
js_result = sb.toString();
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
return list;
}
และส่วนสุดท้ายเราจะนำ string ที่ได้มาแปลงเป็น JSONArray และทำการวนเก็บค่าไว้ใน HashMap ท้ายสุดเราก็จะทำการเก็บ HashMap ไว้ใน ArrayList อีกทีหนึ่งเพื่อเป็นผลลัพธ์ของฟังก์ชั่น (HashMap เก็บข้อมูลของ user หนึ่งคนและเมื่อใส่ใน ArryaList ก็จะแทน user ทั้งหมดที่เป็นคำตอบของการ select)
!! หาก logcat แสดงข้อมูลว่า “Error parsing data ….” แสดงว่าไม่สามารถแปลงผลลัพธ์ที่ได้จาก php มาเป็น JSONArray ส่วนมากแล้วจะมากจากผลลัพธ์ที่ได้จาก php ผิดพลาด
try {
final JSONArray jArray = new JSONArray(js_result);
for (int i = 0; i < jArray.length(); i++) {
JSONObject jo = jArray.getJSONObject(i);
HashMap<String, String> user = new HashMap<String,String>();
user.put("id", jo.get("id").toString());
user.put("username", jo.get("username").toString());
user.put("pass", jo.get("pass").toString());
list.add(user);
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
return list;
}
MainActivity.java
ส่วนของ MainActivity ทำหน้าที่ในการขอผลลัพธ์จากฟังก์ชั่น selectAllUser มาแสดงผลใน ListView (โค้ดบรรทัดที่ 4 และ 5 เป็นการขออนุญาติในการเชื่อมต่ออินเตอร์เน็ตใน main thread)
1: protected void onCreate(Bundle savedInstanceState) {
2: super.onCreate(savedInstanceState);
3: setContentView(R.layout.activity_main);
4: StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
5: StrictMode.setThreadPolicy(policy);
6: listView = (ListView)findViewById(R.id.listView);
7: ArrayList<HashMap<String,String>> result = MysqlConnector.selectAllUser();
8: String[] resultList = new String[result.size()];
9: Log.e("test", result.size()+"");
10: for(int i = 0;i<result.size();i++){
11: resultList[i] = result.get(i).get("username");
12: }
13: ArrayAdapter<String> atdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,resultList);
14: listView.setAdapter(atdapter);
15: }
ในส่วนของการอธิบายโค้ดตัวอย่างก็จบแต่เพียงเท่านี้ครับ ซึ้งตัวอย่างนี้ก็แสดงถึงภาพรวมในการทำให้แอนดรอยด์แอพพลิเคชั่นเชื่อมต่อฐานข้อมูล Mysql ผ่าน php คิดว่าตัวอย่างนี้จะทำให้ผู้อ่านเข้าใจและนำไปประยุกต์ใช้ได้ครับ บทความต่อไปจะนำฟังก์ชั่น พื้นฐานในการทำงานร่วมกับฐานข้อมูลเช่น insert, update, delete มาเป็นตัวอย่างครับ
ผลลัพธ์ตัวอย่าง
รูปที่ 5 แสดงผลลัพธ์การเชื่อมต่อฐานข้อมูล Mysql บนแอนดรอยด์แอพพลิเคชั่น