الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

كيفية التعامل مع قواعد البيانات SQLite مع الاندرويد

بدأه Mahmoud Kelany في 11 أكتوبر 2012 · 5 رد · 19,328 مشاهدة · في Android
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمه الله وبركاته

ان شاء الله اليوم هنشرح مع بعض كيفيه التعامل مع قواعد البيانات 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();
	}
}

فهناك لكل داله جزء خاص بها للتعامل معها

اعتقد انه بسيط جدا على ان يتم شرحه

ولاى استفسار انا موجود ان شاء الله

post-217802-005424000 1349904707_thumb.p

لتحميل المشروع

TestSQLHelper.zip

بالتوفيق ان شاء الله

المرفقات
device-2012-10-10-233135.png

تم تعديل هذه المشاركة بواسطة Mahmoud Kelany في 11 أكتوبر 2012 في 00:44

2

Software Developer
Mahmoudkelany.com


 

#2

مشكور اخي الكريم على مجهودك المميز و شرحك الراقي 

و كان عندي استفسار بخصوص جلب البيانات من القاعدة و عرضها بشكل عشوائي في textview 

من غير button شكر ا مقدما :)

#3
aasameer كتب:

مشكور اخي الكريم على مجهودك المميز و شرحك الراقي 

و كان عندي استفسار بخصوص جلب البيانات من القاعدة و عرضها بشكل عشوائي في textview 

من غير button شكر ا مقدما :)

سؤالك غير واضح ممكن التوضيح اكثر؟

Software Developer
Mahmoudkelany.com


 

#4

مقال توضيحي جيد 


بارك الله فيك 


 


يشكل المقال خطوة جيده في إستعمال قاعدة البيانات في أندرويد ... لكن أريد أن أذكر المبرمجين الجدد أن هناك تغيرات عدة في أندرويد ، سيما إستعمال ال-CURSORLOADER و-CONTENTPROVIDER وغيره .... 


تم تعديل هذه المشاركة بواسطة issamux في 20 نوفمبر 2013 في 18:28

لا إله إلا الله محمد رسول الله  

Blog

GitHub

#5

شكرا على هذا الشرح انا عندي استفسار عن كيفية جلب بيانات من قاعدة بيانات sql server وشكرا

#6

تعني جلب معلومات من MS SQL SERVER إنطلاقاً من برنامج أندرويد ؟


إن كان هذا هو سؤالك ... فالجواب ؛  حالياً أفضل وأسهل طريقة هي إستعمال WebService ...وإستقبال المعلومات على هيئة Json أو XML أو غيره .... إذاً لابد من بوابة PROXY برنامج أو ماشابه ذلك ، و بين الخادم  SQL ....

والله أعلم  :)

لا إله إلا الله محمد رسول الله  

Blog

GitHub

مواضيع مشابهة