السلام عليكم ورحمه الله وبركاته
ان شاء الله اليوم هنشرح مع بعض كيفيه التعامل مع قواعد البيانات SQLite مع الاندرويد
حيث انها قاعده البيانات التى توجد على الموبيل Android لكن يمكن التعامل مع قواعد البيانات الاخرى
مثل الـ MySQL ولكن يكون ذلك على remote server ويتم التعامل معاها عن طريق الـ Webservices
لكى يتم التعامل مع قواعد البيانات فهناك فئه تدعم ذلك وهى SQLiteOpenHelper
وهى من تمكننا من التعامل مع قواعد البيانات بكل سهوله ويسر
نقوم بالوراثه من هذه الفئة فيكون لدينا دالتين onCreate التى تستدعى فى حاله انشاء قاعده البيانات لاول مره
وداله onUpgrade التى تستدعى فى حين عمل تحديثات وهى عاده ما يقوم فيها باسقاط الجداول وتكوينها من جديد
سوف نقوم فى شرحنا ببناء جدول مكون من الاعمدة ID , NAME , AGE وهو جدول بسيط جدا لكى يتم تسهيل عمليه الشرح
قومنا بحفظ اسماء الاعمدة واسم الجدول وقاعده البيانات فى متغيرات لكى يسهل استخدامهم مره اخرى فى اى مكان فالكود هكذا
private String KEY_ID = "ID"; private String KEY_NAME = "NAME"; private String KEY_AGE = "AGE"; private static String DB_NAME = "SQLTEST"; private String DB_TABLE_NAME = "myTable"; private static int DB_VERSION = 1;
فى داله الـ onCreate نقوم باستخدام المتغير db الموجود من ضمن احد مدخلاتها
ونقوم باستدعاء الداله execSQL وهى من تقوم بعمل تنفيذ لامر خاص بقواعد البيانات
ونقوم بكتابه الامر الخاص ببناء الجدول
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + DB_TABLE_NAME + " (" + KEY_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT , " + KEY_NAME
+ " TEXT ," + KEY_AGE + " INTEGER );");
}ولكن فى الداله onUpgrade نقوم كما قولنا فالسابق باسقاط الجدول الذى تم انشاءه من الداله onCreate
واعاده انشائه مره اخرى عن طريق استدعاء الداله onCreate من داخل الداله onUpgrade لاعادة الانشاء
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_NAME);
onCreate(db);
}وبهذا يكون قد تم ان شاء الجدول
لكن لم نتكلم عن كيفيه انشاء قاعده البيانات نفسها فهل هذا الجدول بمفرده هكذا فى الهواء الطلق ؟؟؟
الاجابه : لا
لان فى البناء الخاص بالفئه التى نتعامل معاها نقوم باستدعاء الـ super
ونقوم باعطائه اسم القاعده ورقم اصدارها
super(context, DB_NAME, null, DB_VERSION);
وبهذا نكون قد انشأنا قاعده البيانات والجدول
لكن كيفيه عمل ادراج او تعديل او حذف على قاعده البيانات
لعمل ذلك هناك دالتين فى الفئه SQLiteOpenHelper
getReadableDatabase وهى من تقوم بجعل قاعده البيانات للقرائه فقط
لكننا نحتاجها للتعديل والاضافه فلذلك سوف نستخدم الداله getWritableDatabase
والتى تعود لنا بكائن من الفئة SQLiteDatabase
SQLiteDatabase database = getWritableDatabase();
فى هذا المثال قومنا باستخدام الـ MVC design pattern
وهو ان تقوم بعمل bean class تمثل الجدول الموجود فى قاعده البيانات
لان عندنا نقوم بعمل استدعاء لكل الصفوف فى قاعده البيانات
فكل كائن من النوع Info يمثل صف فى قاعدة البيانات
public class Info {
private int id;
private String name;
private int age;
public Info() {
}
public Info(String name, int age) {
this.name = name;
this.age = age;
}
public Info(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}لكى نقوم باستدعاء (select) جميع الصفوف الموجوده فى قاعده البيانات قومنا بانشاء داله تقوم بذلك
وتعود الينا بمصفوفه من النوع Info تمثل جميع الصفوف فى قاعده البيانات
public Info[] selectAll() {
String columns[] = new String[] { KEY_ID, KEY_NAME, KEY_AGE };
Cursor c = database.query(DB_TABLE_NAME, columns, null, null, null,
null, null);
int idIndex = c.getColumnIndex(KEY_ID);
int nameIndex = c.getColumnIndex(KEY_NAME);
int ageIndex = c.getColumnIndex(KEY_AGE);
List<Info> list = new ArrayList<Info>();
if (c.moveToFirst()) {
do {
list.add(new Info(c.getInt(idIndex), c.getString(nameIndex), c
.getInt(ageIndex)));
} while (c.moveToNext());
}
return list.toArray(new Info[list.size()]);
}لكى نقوم بتنفيذ الاستدعاء نقوم باستدعاء الداله query على الـdatabase
ونقوم باعطائها اسم الجدول ومصفوفه من اسماء الاعمدة التى تريد ان تقوم باحضارها
وليس هناك اى شروط او ترتيب او اى شىء اخر فجميع القيم تكون عباره عن null
تعود لنا النتيجه فى كائن من الفئة Cursor
لكى نحصل على البيانات من الـ Cursor لابد وان نعمل ترتيب اسم العمود فى قاعده البيانات
لكن هناك وسيلة افضل ان نقوم بالحصول على رقم العمود من اسمه
هكذا
int idIndex = c.getColumnIndex(KEY_ID); int nameIndex = c.getColumnIndex(KEY_NAME); int ageIndex = c.getColumnIndex(KEY_AGE);
ونقوم ببناء قائمه من الـ Info لاننا لا نعلم كم عدد الصفوف فى قاعده البيانات
نقوم بعمل لووب على البيانات نقوم بتفحص البيانات والذهاب لاول صف
واخد البيانات منه وبعد ذلك التحرك للامام
فأفضل طريقه للتعامل مع ذلك هو الـ do...while loop
وبداخل اللوب نقوم باخد البيانات عن طريق نوعها getXXX هناك جميع الانواع المتاحه مع قاعده البيانات
وباستخدام رقم العمود التى تم الحصول عليه من قبل
ونكون كائن من نوع Info ونضعه فى الـ list
حتى تنتهى اللوب ونقوم بتحويل الـ list الى Array
وذلك حصلنا على جميع البيانات
وسوف نقوم بشرح كيفيه عرض هذه البيانات الموجوده فى المصفوفه ان شاء الله
الداله selectOne وهى من تجلب صف من قاعده البيانات بناء على شرط معين
public Info selectOne(int id) {
String columns[] = new String[] { KEY_ID, KEY_NAME, KEY_AGE };
Cursor c = database.query(DB_TABLE_NAME, columns, KEY_ID + " = " + id,
null, null, null, null);
int idIndex = c.getColumnIndex(KEY_ID);
int nameIndex = c.getColumnIndex(KEY_NAME);
int ageIndex = c.getColumnIndex(KEY_AGE);
if (c != null && c.moveToFirst()) {
return new Info(c.getInt(idIndex), c.getString(nameIndex),
c.getInt(ageIndex));
}
return null;
}هى نفس الـ SelectAll ولكن الجديد هو الشرط
فهناك المدخل الثالث للداله query قومنا بوضع الشرط KEY_ID + " = " + id وهو مخصص لشرط جلب البيانات
نأتى بعد ذلك لعمليه ادراج البيانات (insert) ولذلك قومت ببناء داله تأخذ كائن من الـ Info وتقوم بوضع بياناته فى قاعده البيانات
public long insert(Info info) {
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, info.getName());
cv.put(KEY_AGE, info.getAge());
return database.insert(DB_TABLE_NAME, null, cv);
}لكن لوضع البيانات فى قاعده البيانات نقوم باستدعاء الداله insert التى تأخد اسم الجدول
وهل يسمح باضافه صف فى قاعده البيانات اذا كانت محتوياته تحتوى على null فنحن لا نريد ذلك فلذلك وضعنا القيمه الافتراضيه null
والمدخل الاخير يأخذ كائن من النوع ContentValues وهو ما يشبة كثير بالـ Hashmap
نقوم بعملها وتسكين المتغيرات بداخلها , المفتاح والقيمه
وبعدها نقوم بعمليه ادراج البيانات
الداله update تشبه كثيرا الداله insert
لكنها لديها اختلاف بسيط هو شرط التعديل
public long update(Info info) {
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, info.getName());
cv.put(KEY_AGE, info.getAge());
return database.update(DB_TABLE_NAME, cv,
KEY_ID + " = " + info.getId(), null);
}فهى تأخذ اسم الجدول
والقيم المعدلة
وشرط التعديل where
ومتتغيرات او مدخلات جمله الشرط التعديل ولكن عادة ما نكتب الشرط كاملا ولا نحتاج للمتغيرات فنضعها بـ null
وللداله الخاصه بالحدف delete وهنا يكون الحذف عن طريق المفتاح الاساسى Primary Key
public long delete(int id) {
return database.delete(DB_TABLE_NAME, KEY_ID + " = " + id, null);
}نستخدم الداله delete ومن مدخلاتها اسم الجدول والشرط ومتغيرات الشرط
وبهذا نقوم قد شرحنا كيفيه التعامل مع قواعد البيانات
وشرح كتابه الخمس دوال الاساسية التى يحتاجها اى جدول فى قاعده البيانات من (selectAll , selectOne , insert , update , delete)
وهذا الكود كاملا لما سبق
package com.jkelany.sql;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class InfoServices extends SQLiteOpenHelper {
private String KEY_ID = "ID";
private String KEY_NAME = "NAME";
private String KEY_AGE = "AGE";
private static String DB_NAME = "SQLTEST";
private String DB_TABLE_NAME = "myTable";
private static int DB_VERSION = 1;
private SQLiteDatabase database;
public InfoServices(Context context) {
super(context, DB_NAME, null, DB_VERSION);
database = getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + DB_TABLE_NAME + " (" + KEY_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT , " + KEY_NAME
+ " TEXT ," + KEY_AGE + " INTEGER );");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_NAME);
onCreate(db);
}
public Info[] selectAll() {
String columns[] = new String[] { KEY_ID, KEY_NAME, KEY_AGE };
Cursor c = database.query(DB_TABLE_NAME, columns, null, null,null,null,null);
int idIndex = c.getColumnIndex(KEY_ID);
int nameIndex = c.getColumnIndex(KEY_NAME);
int ageIndex = c.getColumnIndex(KEY_AGE);
List<Info> list = new ArrayList<Info>();
if (c.moveToFirst()) {
do {
list.add(new Info(c.getInt(idIndex), c.getString(nameIndex), c
.getInt(ageIndex)));
} while (c.moveToNext());
}
return list.toArray(new Info[list.size()]);
}
public Info selectOne(int id) {
String columns[] = new String[] { KEY_ID, KEY_NAME, KEY_AGE };
Cursor c = database.query(DB_TABLE_NAME, columns, KEY_ID + " = " + id,
null, null, null, null);
int idIndex = c.getColumnIndex(KEY_ID);
int nameIndex = c.getColumnIndex(KEY_NAME);
int ageIndex = c.getColumnIndex(KEY_AGE);
if (c != null && c.moveToFirst()) {
return new Info(c.getInt(idIndex), c.getString(nameIndex),
c.getInt(ageIndex));
}
return null;
}
public long insert(Info info) {
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, info.getName());
cv.put(KEY_AGE, info.getAge());
return database.insert(DB_TABLE_NAME, null, cv);
}
public long update(Info info) {
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, info.getName());
cv.put(KEY_AGE, info.getAge());
return database.update(DB_TABLE_NAME, cv,
KEY_ID + " = " + info.getId(), null);
}
public long delete(int id) {
return database.delete(DB_TABLE_NAME, KEY_ID + " = " + id, null);
}
}يبقى فقط عملية العرض وهى من المفترض ان يكون المبرمج على درايه بها
لكن لا بأس من عرض كيفيه استخدام ذلك حيث ان ممكن ان يكون نظام الـ MVC جديد على بعض الناس
فلدينا الفئة InfoServices وهى ما تقوم بالتعامل مع قاعده البيانات و هى ما نتكلم عليها طول شرحنا
والفئة Info وهى من تحمل البيانات
والان سوف نقوم باستخدامهم فى الـTestSQLHelperActivity
package com.jkelany.sqlhelper;
import com.jkelany.sql.Info;
import com.jkelany.sql.InfoServices;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class TestSQLHelperActivity extends Activity {
private InfoServices infoServices;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = (TextView) findViewById(R.id.tv_sql_rs);
infoServices = new InfoServices(this);
// insert
infoServices.insert(new Info("Mahmoud Kelany", 21));
// select one
Info info = infoServices.selectOne(1);
info.setAge(22);
// update
infoServices.update(info);
// select all
Info[] rs = infoServices.selectAll();
String result = "";
for (int i = 0; i < rs.length; i++) {
result += rs.getId() + " - " + rs.getName() + "("
+ rs.getAge() + ")\n";
}
tv.setText(result);
// delete id = 1
infoServices.delete(1);
infoServices.close();
}
}فهناك لكل داله جزء خاص بها للتعامل معها
اعتقد انه بسيط جدا على ان يتم شرحه
ولاى استفسار انا موجود ان شاء الله
لتحميل المشروع
بالتوفيق ان شاء الله