آموزش دیتابیس در اندروید (SQLite) + سورس پروژه

آموزش دیتابیس SQLite در اندروید
دیتابیس یا پایگاه داده یکی از مهمترین قسمت‌های هر نرم‌افزار و اپلیکیشن به‌شمار می‌رود که برنامه‌های اندرویدی هم از این قاعده مستثنی نیستند. در این قسمت از سری مباحث آموزش برنامه نویسی اندروید قصد داریم با مفهوم و کاربرد دیتابیس آشنا شده سپس به نحوه‌ی پیاده‌سازی دیتابیس SQLite در اندروید بپردازیم.

 

این جلسه در قالب PDF و در ۸۴ صفحه تهیه شده که در ادامه چند صفحه‌ ابتدایی را مشاهده می‌کنید:

دیتابیس چیست؟

بهتر است قبل از آنکه وارد حوزه‌ی اندروید و دیتابیس SQLite شویم، با مفهوم کلی دیتابیس و نقش آن در نرم‌افزارها آشنا شویم.
هر سه واژه‌ی دیتابیس، پایگاه داده و بانک اطلاعاتی در زبان فارسی برای اشاره به مفهوم Database به‌کار می‌رود. بنابراین در هر منبع و مقاله‌ای که با یکی از این واژه‌ها برخورد داشتید بدانید که مقصود یکیست و تفاوتی بین آنها وجود ندارد.
البته در اغلب موارد در منابع فارسی، واژه‌ی دیتابیس مورد استفاده قرار می‌گیرد؛ بنابراین من هم در این آموزش همین رویه را درپیش می‌گیرم.

دیتابیس چیست؟
دیتابیس چیست؟

در ابتدا به بیان تعریف دیتابیس می‌پردازیم. به طور خلاصه به مجموعه‌ای از داده‌ها با ساختار منظم و سامان‌مند، دیتابیس گفته می‌شود.
دسترسی و مدیریت داده‌های ذخیره شده در دیتابیس عموماً از طریق سیستم‌های مدیریت پایگاه داده یا Database Management System انجام می‌گیرد که به‌اختصار DBMS یا RDBMS نامیده می‌شوند. منظور از مدیریت داده‌ها انجام عملیاتی مانند اضافه کردن، حذف و ویرایش داده است.
به‌عبارت‌دیگر، ما با استفاده از یک واسط شامل DBMSها می‌توانیم داده‌های مدنظر را روی Database ذخیره و بازیابی کنیم.
شاید کمتر نرم‌افزار یا اپلیکیشنی را بتوان پیدا کرد که نیازی به دیتابیس و ذخیره‌سازی داده نداشته باشد. مهم نیست نرم‌افزار برای سیستم‌عامل Windows ساخته شده یا Android یا iOS. هر نرم‌افزار یا اپلیکیشنی برای ذخیره‌ی تنظیمات خود و همچنین داده‌های موردنیاز کاربر به یک دیتابیس نیاز دارد.
کاربر به واسطه‌ی نرم‌افزاری که در اختیارش قرار می‌گیرد می‌تواند داده‌های متعددی را روی دیتابیس ذخیره، مشاهده و یا ویرایش کند. البته این به معنی ارتباط مستقیم کاربر با دیتابیس و داده‌های موجود در آن نیست. کاربر با رابط گرافیکی برنامه (UI) که محیط نرم افزار هم نامیده می‌شود ارتباط برقرار کرده و هیچ تماس مستقیمی با دیتابیس ندارد. این وظیفه‌ی برنامه است که دستورات کاربر را از رابط گرافیکی دریافت کرده و در دیتابیس خود ذخیره کند.

یک مثال از کاربرد دیتابیس

بگذارید یک مثال ساده از دیتابیس بگویم تا کارکرد و نحوه‌ی ارتباط کاربر با آن را بهتر درک کنید. یک اپلیکیشن موبایلی یا نرم‌افزار ویندوزی را درنظر بگیرید که به‌منظور یادداشت برداری ساخته شده‌است. به‌عبارت‌دیگر، یک دفترچه یادداشت دیجیتال را درنظر می‌گیریم.

اپلیکیشن دفترچه یادداشت
اپلیکیشن دفترچه یادداشت

با استفاده از این برنامه، کاربر در هر زمانی می‌تواند یک یادداشت متنی روی آن ذخیره کند. همچنین در صورت لزوم می‌تواند یادداشتی که قبلاً ذخیره کرده را مشاهده، ویرایش و یا به‌طور کامل از برنامه حذف کند.
کاربر در اینجا هیچ اطلاعی در مورد دیتابیس و پشت‌صحنه‌ی چگونگی ذخیره‌ی داده‌ها روی دستگاه نداشته و صرفاً در محیط برنامه و با استفاده از رابط گرافیکی، یادداشت‌های خود را ذخیره می‌کند.
فرایندی که در این نرم‌افزار طی می‌شود به اینصورت است که رابط گرافیکی برنامه (شامل یک فیلد متنی اصلی و یا چندین فیلد جانبی دیگر) متن نوشته‌شده توسط کاربر را دریافت کرده و به سیستم مدیریت دیتابیس یا DBMS انتقال می‌دهد. در نهایت، این سیستم متن دریافتی را در قالب داده‌های ساختاریافته و منظم روی دیتابیس ذخیره می‌کند.

ضرورت استفاده از دیتابیس

پرسشی که ممکن است به ذهن برخی خطور کند این است که “خب چرا دیتابیس؟” اپلیکیشن را می‌توان به‌گونه‌ای ساخت که یادداشت‌های کاربر را درون یک فایل متنی ساده (txt) ذخیره کرده و در موقع نیاز از همان فایل فراخوانی کند!
در جواب باید گفت که نظرتان تا حدودی درست است. چه‌بسا همین الان هم بتوان برنامه‌هایی را یافت که به‌جای دیتابیس، داده‌های خود را به‌صورت متن ساده ذخیره می‌کنند. اما این روش معایب متعددی دارد که در اینجا به مهم‌ترین آنها اشاره می‌کنیم:

  • عدم امنیت کافی: شاید برای یک برنامه یادداشت، مسئله‌ی امنیت اطلاعات خیلی جدی به‌نظر نرسد اما در اکثر موارد، داده‌های اصلی برنامه یا داده‌های اضافه‌شده توسط کاربر جنبه‌ی محرمانه داشته و نباید خارج از محیط برنامه قابل مشاهده و بازیابی باشد.
    داده‌ها در دیتابیس SQLite به‌صورت رمزگذاری‌شده ذخیره می‌شود و برخلاف یک فایل ساده‌ی متنی که محتوای آن با هر برنامه‌ی ویرایشگر متنی قابل خواندن است، جز با DBMS آن قابل بازیابی نخواهد بود.
    البته این مسئله شامل همه‌ی دیتابیس‌ها نمی‌شود. برای مثال، در MySQL که بیشتر برای مدیریت دیتابیس وب‌سایت‌ها به‌کار می‌رود، داده‌ها کدگذاری نشده و صرفاً برای ذخیره‌سازی ساختاریافته‌ی داده‌ها مورد استفاده قرار می‌گیرد.
    دیتابیسی مانند SQLite عموماً به صورت محلی (Local) و روی دستگاه کاربر (موبایل، کامپیوتر و…) ذخیره می‌شود و به‌همین دلیل است که این نوع دیتابیس‌ها عموماً رمزگذاری می‌شوند. این درحالی است که دیتابیسی مانند MySQL که برای مدیریت داده‌ی وب‌سایت‌ها استفاده می‌شود، روی سرور مرکزی ذخیره شده و کاربر دسترسی مستقیم به آن ندارد؛ بنابراین نیازی هم به رمزگذاری آن نیست.
  • عدم ساختار دادن به داده‌ها: داده‌ها در یک فایل متنی به‌صورت ساده ذخیره شده و امکان سامان‌دهی و ایجاد ارتباط بین آنها وجود ندارد. این مسئله علاوه بر کاهش سرعت ذخیره و بازیابی، حجم داده‌های ذخیره‌شده را نیز تا چندین برابر افزایش می‌دهد.
    فرض کنید یک بانک برای ذخیره‌ی داده‌های مشتریان خود شامل تراکنش‌های بانکی و اطلاعات حساب، از فرمت متنی استفاده کند! کافیست فقط چند روز از آغاز به‌کار ذخیره‌سازی داده‌ها بگذرد تا هنگام دریافت و ارسال داده از شعبه‌ها به مرکز، سیستم با مشکلات جدی مواجه شود.
نکته: اگر مایلید در مورد تفاوت‌های ذخیره‌ی داده روی فایل Text و Database اطلاعات بیشتری کسب کنید، عبارتی مانند “database vs text file” را گوگل کنید.

انواع دیتابیس

دیتابیس در همه‌جا کاربرد دارد. از اپلیکیشن‌های مختلف گوشی‌های هوشمند گرفته تا نرم‌افزارهای کاربردی رایانه‌ها، سرورهای بانکها، سازمانها و … .
اگر قبلاً در حوزه طراحی وب‌سایت فعالیت کرده‌اید حتما واژه‌هایی مانند MySQL و SQLServer را بارها شنیده و یا با آنها سروکار داشته‌اید. اینها هم مانند SQLite یک DBMS از نوع رابطه‌ای (Relational) هستند بنابراین Relational Database Management System یا RDBMS نامیده می‌شوند.
تفاوت عمده‌ی این RDBMSها در این است که مواردی مانند MySQL و SQLServer روی سرورهای مرکزی و به‌منظور پردازش و ذخیره‌سازی دیتابیس‌های متوسط و حجیم مورد استفاده قرار می‌گیرند درحالی که موردی مانند SQLite برای مدیریت دیتابیس‌های کوچک و محلی (ذخیره‌شده روی دستگاه کاربر) استفاده می‌شود.
منظور از Relational این است که داده‌های موجود در دیتابیس با یکدیگر در ارتباط بوده و به‌صورت سطر و ستون‌های منظمی ذخیره می‌شوند. جدول زیر یک مثال ساده از این نوع دیتابیس است:

شناسه نام نام خانوادگی سن
۱ مهدی جرجانی ۲۶
۲ مریم محمدی ۲۴

جدول بالا نمونه‎ی ساده‌ی یک دیتابیس است که شامل ۴ ستون و ۲ ردیف می‌باشد. اطلاعات جدول (ردیف‌ها) توسط کاربر و به واسطه نرم افزار مدیریت دیتابیس در هر زمان قابل اضافه، ویرایش و حذف شدن است.
DBMSهای متعددی توسط شرکت‌ها و تیم‌های مختلف ساخته شده و در دسترس توسعه دهندگان قرار گرفته است که بجز ۳ موردی که در بالا اشاره شد، به مواردی مانند ORACLE و Microsoft ACCESS می‌توان اشاره کرد.
به عنوان مثال از ORACLE (اوراکِل) برای بانک‌های اطلاعاتی با حجم بسیار بالا استفاده می شود (مانند بانک‌ها و سازمان‌های دولتی و خصوصی بزرگ). یا اگر تابحال با سیستم‌های مدیریت محتوای وب مانند WordPress و Joomla کار کرده‌اید حتماً با MySQL آشنایی مختصری دارید.
عموماً از MySQL برای وب سایت‌های با حجم داده در حد کم و متوسط استفاده می شود. اما وجه اشتراک موارد بالا در SQL است. SQL مخفف Structured Query Language و معنی لغوی آن “زبان ساختارمند پرسش ها” است. زبان SQL یک زبان استاندارد بوده که شامل دستوراتی برای مدیریت اطلاعات دیتابیس ها می باشد. از جمله دستورات کلیدی SQL می توان به INSERT، UPDATE، DELETE، SELECT و DROP اشاره کرد.
چهار عمل اصلی پایگاه داده ها Create (ایجاد)، Read (خواندن)، Update (بروزرسانی) و Delete هستند که به اختصار CRUD نامیده می شود.
اگر آشنایی قبلی با دیتابیس ندارید قطعاً مفاهیم بالا مقداری شما را گیج کرده است. اما جای نگرانی نیست. اولاً اینکه در عمل ما با مفاهیم سروکار نداریم و صرفاً از این جهت به خلاصه‌ای از پایگاه داده‌ها اشاره کردم تا یک پیش‌زمینه کلی در ذهن شما ایجاد شود. دوم اینکه دانستن این اطلاعات درک عمیق‌تری از پایگاه‌های داده به شما می‌دهد و چه خوب است در کنار مباحث اصلی دیتابیس، اندکی هم در وب در خصوص دیتابیس‌ها مطالعه کنید.

SQLite چیست؟

بهتر است بیشتر از این از مبحث اصلی یعنی آموزش دیتابیس در اندروید و مبحث SQLite منحرف نشویم. در پاراگراف بالا اشاره شد که هرکدام از برنامه‌های مدیریت بانک اطلاعاتی بنا به ویژگی‌هایی که دارد، در مقاصد خاصی استفاده می‌شود.

دیتابیس SQLite
دیتابیس SQLite

در دیوایس های اندروید که عموماً گوشی‌، تبلت و ساعت‌های هوشمند هستند، دیتابیس‌ها حجم بسیار کمی را در بر می‌گیرند بنابراین لازم است از سیستمی استفاده شود که کمترین میزان از منابع سخت افزاری دیوایس از جمله حافظه RAM و CPU را درگیر کرده و حجم خود اپلیکیشن نیز تا حد ممکن کم باشد.
گوگل سیستم SQLite را برای اندروید برگزیده که به صورت پیش‌فرض درون این سیستم‌عامل تعبیه شده و شما به عنوان توسعه‌دهنده‌ی اپلیکیشن نیازی به نصب SQLite بر روی دیوایس کاربر ندارید. ما فقط دیتابیس را ایجاد کرده و به واسطه دستورات SQL آنرا مدیریت می‌کنیم. SQLite یک پایگاه داده بسیار کوچک با حجمی کمتر از یک مگابایت است که در قالب یک کتابخانه (Library) نوشته شده و به صورت اوپن سورس و رایگان منتشر شده است.
بنابراین گوگل یا توسعه دهنده نیازی نیست برای استفاده از این پایگاه داده مبلغی را به سازنده بپردازند. همچنین بر خلاف دیتابیسی مانند MySQL که نیاز به سرور دارد، SQLite بی نیاز از سرور بوده و به صورت مستقل روی هر دیوایس مستقر شده که اصطلاحاً ServerLess نامیده می‌شود.

آشنایی اولیه با SQLite و استفاده از ابزار مدیریت آن

بهتر است قبل از اینکه سراغ استفاده از دیتابیس در اندروید برویم قدری با این پایگاه داده و زبان SQL در محیط گرافیکی و ویژوال آشنا شویم تا درک بهتری از مفاهیم مرتبط با آن کسب کنیم. ابزارهای مختلفی برای کار با SQLite منتشر شده‌اند که امکانات و محیط کار همگی تا حدی مشابه بوده و امکان ساخت دیتابیس، جداول، ستون‌ها، ورود داده‌ها، حذف داده‌ها و … در همه آنها و در یک محیط گرافیکی و ساده وجود دارد.
با استفاده از این ابزار نیاز ما به نوشتن مستقیم دستورات SQL رفع می‌شود و بجای آن، داده‌ها را در یک محیط گرافیکی وارد دیتابیس می‌کنیم. این ابزار، دستورات ما را دریافت کرده و به دستورات SQL تبدیل می‌کنند. اعتبارسنجی دستورات از دیگر مزیت‌های این ابزار به‌شمار می‌رود.
از معتبرترین ابزارهای کار با SQLite می‌توان به SQLiteStudio ، DB Browser for SQLite و SQLite Expert Personal اشاره کرد. البته نسخه‌ای از برنامه SQLite Expert با نام Professional هم در وب‌سایت آن موجود است که رایگان نبوده و لازم است خریداری شده یا از نسخه‌های کرک شده استفاده شود.
برای این آموزش، استفاده از ابزار رایگان کافی بوده و نیاز ما را برآرده می‌کند. حتی پلاگینی به این منظور برای مرورگر FireFox به صورت رایگان منتشر شده که با نصب آن روی فایرفاکس می‌توانید به مدیریت دیتابیس‌های SQLite بپردازید. این پلاگین SQLite Manager نام دارد. محیط کاربری این ابزارها تا حدودی مشابه یکدیگر بوده و پیچیدگی را احساس نخواهید کرد.
در این آموزش من از SQLiteStudio استفاده می کنم.
تاکید می‌کنم استفاده از این ابزار در این مبحث آموزشی فقط برای آشنایی با دیتابیس و دستورات SQL و اطمینان از صحت دستوراتی است که بنا به نیازمان می‌نویسیم و قرار نیست ما دیتابیس خروجی این ابزار را به پروژه اندرویدی خود منتقل کنیم.
من SQLiteStudio را از وب‌سایت رسمی آن دانلود و نصب می‌کنم.

تذکر: امیدوارم این ابزار مدیریت دیتابیس در محیط دسکتاپ را با برنامه‌های مدیریت دیتابیس (DBMS) اشتباه نگیرید!
به‌طور خلاصه، در اینجا ما قصد داریم با ابزاری به‌نام SQLiteStudio، از طریق یک رابط گرافیکی ساده، با سیستم مدیریت دیتابیس (DBMS) که SQLite نام دارد ارتباط برقرار کنیم.

SQLiteStudio را باز می‌کنم:

نرم افزار SQLiteStudio
نرم افزار مدیریت دیتابیس SQLiteStudio

در قدم نخست لازم است یک دیتابیس جدید ایجاد کنم. به منوی Database رفته و گزینه Add a database را انتخاب می‌کنم:

ساخت دیتابیس جدید در SQLiteStudio
ساخت دیتابیس جدید در SQLiteStudio
تعیین نام پایگاه داده SQLite
تعیین نام پایگاه داده SQLite

قسمت Database type که مربوط به نوع دیتابیس می‌شود را بدون تغییر رها کرده و به سراغ فیلد انتخاب نام دیتابیس می‌روم. با کلیک روی آیکون پوشه، پنجره انتخاب محل ذخیره فایل دیتابیس باز می‌شود.
نام مدنظر خود را وارد کرده و تایید می‌کنم:

تعیین نام دیتابیس

من نام test_db را در فیلد File name وارد کردم. با کلیک روی دکمه Select، اطلاعات دیتابیس ایجاد شده به‌صورت زیر نمایش داده می‌شود:

ساخت دیتابیس SQLite

در تصویر بالا ملاحظه می‌کنید پسوند .db به‌صورت خودکار به نام فایل اضافه شده است. روی دکمه OK کلیک می‌کنم تا دیتابیس به منوی سمت چپ اضافه شود. با دوبار کلیک روی نام دیتابیس یا کلیک روی فلش سمت چپ آن، گزینه‌های زیرمجموعه آن باز می‌شود که اولی Tables به معنی جدول‌ها نام دارد.
هر دیتابیس از حداقل یک جدول تشکیل شده که اطلاعات را درون خود نگهداری می‌کند. با راست کلیک روی گزینه Tables و یا آیکون آن در نوار بالای برنامه می‌توان جدول یا جدول‌های موردنیاز را به دیتابیس افزود:

افزودن جدول به دیتابیس
افزودن جدول به دیتابیس
تعیین نام جدول
تعیین نام جدول

در قسمت Table name یک نام برای جدول تعیین می کنیم. من نام person_details را وارد کردم. قبل از ساخت جدول حداقل یک ستون می‌بایست به جدول اضافه کنیم. ساختار دیتابیس و جدول را همین ستون‌ها تشکیل می‌دهند. عموما برای هر ردیف از اطلاعات یک شناسه (ID) اختصاص می‌دهیم که این شناسه به صورت افزایشی و غیر قابل تکرار می‌باشد. با زدن گزینه Add column پنجره‌ای باز می شود که مشخصات ستون را باید وارد کنیم:

افزودن ستون به جدول دیتابیس
افزودن ستون به جدول دیتابیس

افزودن ستون به جدول دیتابیس

پنجره‌ی فوق باز می‌شود. برای فیلد Column name مقدار (نام) دلخواه id و Data type را از نوع INTEGER انتخاب می‌کنم. شناسه از نوع عدد صحیح بوده بنابراین می‌بایست INTEGER باشد.

نکته: اگر لازم است بیشتر در مورد نوع داده ها بدانید با یک جستجو در وب به پاسخ‌های زیادی می‌رسید. جستجو در وب و یا به اصطلاح گوگل کردن، سلاح همیشه همراه برنامه نویسان، توسعه دهندگان و طراحان وب است! حتی حرفه‌ای ترین افراد هم در زمان کار روی پروژه‌های خود نیاز به جستجو دارند. همیشه جزئیاتی هستند که به علت حجم بالای اطلاعات از ذهن انسان پاک شده و نیاز به مرور دارد.
در بیشتر موارد رجوع به وب سریع‌تر شما را به نتیجه می‌رساند تا گشتن در میان داکیومنت‌ها و ویدئوهای آموزشی که روی حافظه رایانه خود دارید. به عنوان مثال برای مورد بالا با جستجوی “Data types in Database”، “Data types in SQL”، “Data types in SQlite”، “انواع داده ها در SQL”، “انواع داده ها در دیتابیس”، “انواع داده‌ها در برنامه نویسی” و … به نتایج خوبی می‌رسید که در عرض چند دقیقه با مطالعه ۲ یا ۳ مطلب پاسخ های مناسبی دریافت می‌کنید.
مخصوصاً تمام مواردی که برای جستجو در این خصوص به ذهنم رسید را لیست کردم تا تصور نکنید عبارت جستجوی شما باید خیلی سنجیده و مشخص باشد. ضمن اینکه در دنیای نرم افزار، مشابهات زیاد هستند و نیاز به جستجوی خیلی دقیق در همه موارد نیست.
برای مثال بعد از جستجو در خصوص “انواع داده‌ها” نیاز نیست حتما به دنبال مقاله‌ای بگردید که انواع داده ها را در دیتابیس و در SQLite شرح داده باشد چون داده‌ها در تمامی زمینه‌ها کاربرد یکسانی دارند (یعنی Integer در Java، C++، PHP، SQL و… مفهوم یکسانی دارد).

خب، از آنجایی که id ستون اصلی دیتابیس ماست با ویژگی‌هایی که در قسمت قبل اشاره کردم (افزایشی و غیر قابل تکرار) گزینه Primary Key را انتخاب می‌کنم:

کاربرد Primary Key
کاربرد Primary Key

دکمه Configure برای این گزینه فعال شد. روی دکمه کلیک می‌کنم. گزینه اول Autoincrement به معنی افزایش خودکار است. شناسه هم باید این ویژگی را داشته باشد تا با اضافه شدن هر سطر از اطلاعات جدید، یک رقم به رقم شناسه قبلی به‌صورت خودکار اضافه شود. انتخاب کرده و Apply می‌کنم:

کاربرد Autoincrement
کاربرد Autoincrement

ویژگی دیگری که برای شناسه ذکر شد، یکتا بودن و تکراری نبودن آن‌ها بود. بنابراین گزینه Unique به معنی یکتا را انتخاب و OK می‌کنم:

کاربرد Unique
کاربرد Unique

ستون id با موفقیت به جدول اضافه شد:

اضافه کردن ستون به جدول دیتابیس

به همین ترتیب مابقی ستون‌های مدنظرم را هم اضافه می‌کنم. من چند ستون دیگر با عنوان نام، نام خانوادگی، سن و تلفن تماس مدنظر دارم که آنها را اضافه می‌کنم:

اضافه کردن ستون به جدول دیتابیس

مطابق تصویر بالا من نام ستون دوم را name و نوع آن را TEXT انتخاب کردم. در نسخه‌های قبلی SQLiteStudio علاوه بر TEXT یک دیتا تایپ دیگر با نام VARCHAR هم وجود داشت که برای ذخیره رشته‌های متنی کوتاه استفاده می‌شد؛ اما به دلایلی در نسخه جدید حذف شده است.
معمولا از VARCHAR برای ذخیره داده‌هایی مانند نام افراد، نام شهر و… که تعداد کاراکتر کمی را شامل می‌شود استفاده می‌شود. دیتا تایپ VARCHAR نسبت به TEXT فضای کمتری اشغال می‌کند بااینحال آنقدر تفاوت زیادی هم ندارد.
البته احتمالاً می‌شود به‌جای انتخاب یک گزینه از لیست Data type مقداری دلخواه مانند VARCHAR را داخل فیلد آن تایپ کرد اما از آنجایی که اینجا هدف آشنایی اولیه با دیتابیس SQLite اندروید است خیلی درگیر جزئیات نمی‌شویم.
همانطور که ملاحظه می‌کنید، در اینجا گزینه Primary key غیرفعال است زیرا ما قبلا ستون id را از نوع Primary key انتخاب کرده بودیم و چنانچه قبلاً اشاره شد، هر جدول فقط یک ستون از این نوع می‌تواند داشته باشد.
گزینه Unique هم برای این ستون و ستون‌های دیگر انتخاب نمی‌شود زیرا داده‌هایی مانند نام و سن یکتا نبوده و افراد زیادی ممکن است نام و سن مشترک داشته باشند. البته برای مثال چنانچه قصد داشتیم یک ستون برای کد ملی داشته باشیم می‌توان آن را از نوع یکتا تعریف کرد تا هر کد ملی فقط برای یک شخص قابل ثبت باشد.
به همین ترتیب یک ستون برای نام خانوادگی با نام family و از نوع TEXT، یک ستون برای سن با نام age و از نوع INTEGER و یک ستون برای شماره تلفن با نام tel و از نوع TEXT می‌سازم.
ستون شماره تلفن را باید از نوع عددی یعنی INTEGER می‌ساختیم اما از آنجایی که در داده‌های عددی، صفر ابتدای عدد و همچنین کاراکتریهای غیرعددی (مانند +) هنگام ذخیره سازی روی دیتابیس حذف می‌شود، آن را از نوع TEXT تعریف می‌کنم تا شماره همانطوری که کاربر وارد کرده ثبت شود. شماره موبایل معمولاً با فرمت ۰۹۱۵۱۱۱۱۱۱۱ و یا ۹۸۹۱۵۱۱۱۱۱۱۱+ ثبت می‌شود.
در نهایت ۵ ستون به صورت زیر به جدول person_details اضافه شد. چنانچه هرکدام از ستون‌ها نیاز به تغییراتی داشت، با دوبار کلیک روی ردیف آن، پنجره‌ی تنظیمات مجدد باز می‌شود.

تعریف ستون‌های جدول در دیتابیس
همه ستون‌ها تعریف شد

توجه داشته باشید تغییرات ما شامل اضافه کردن ستون‌ها هنوز ذخیره نشده که با استفاده از کلیدهای Ctrl + S و یا دکمه Commit structure changes که در تصویر بالا مشخص شده، این عمل انجام می‌شود.
پس از انجام یکی از دو عمل فوق، قبل از ذخیره شدن تنظیمات جدول، دستور یا کوئری (Query) مربوط به آن نمایش داده می‌شود:

کوئری (Query) ستون‌های جدول دیتابیس
کوئری (Query) ستون‌های جدول دیتابیس

همانطور که قبلاً اشاره شد، ابزاری مانند SQLiteStudio صرفاً برای سادگی کار استفاده می‌شود. به‌این‌صورت که این ابزار دستورات ما را در رابط گرافیکی خود دریافت کرده و به این کوئری قبل فهم برای SQLite تبدیل می‌کند.
به‌عبارت‌دیگر، این ابزار ما را از نوشتن مستقیم کوئری فوق بی‌نیاز کرده و احتمال خطا در نوشتن دستور را هم ازبین می‌برد.
کوئری فوق را با دقت بررسی کنید. دستور به این صورت است که یک جدول با نام person_details ساخته (CREATE) شود. سپس ستون‌های آن داخل پرانتز لیست شده که نوع داده‌ی هر ستون در جلوی نام آن قید شده است.
با کلیک روی دکمه OK جدول روی دیتابیس ذخیره می‌شود:

ذخیره تغییرات جدول دیتابیس SQLite

جدول به پنل سمت چپ برنامه اضافه شد. همچنین در قسمت Status هم Log مربوط به ذخیره تنظیمات جدول مدنظر ما نمایش داده می‌شود. جرئیات مربوط به ساختار جدول در Tab یا زبانه Structure نمایش داده می‌شود.
آخرین کوئری ساختار جدول همیشه در زبانه DDL قابل مشاهده است.

نکته: تغییر تنظیمات ستون‌ها در هر زمانی ممکن است. فقط به یاد داشته باشید بعد از هر تغییر باید آن را ذخیره کنید.
نکته: Query (کوئری) در زبان فارسی با عنوان “پرس و جو” نیز شناخته می‌شود. تمامی اعمال مربوط به دیتابیس توسط همین کوئری‌ها انجام‌می شود. در ادامه مبحث و در اندروید هم ما با همین کوئری‌ها سروکار داریم و دیگر خبری از ابزار مدیریت دیتابیس مانند SQLiteStudio نیست.

حالا قصد دارم اطلاعات چند شخص را وارد دیتابیس کنم. در تب Data با زدن گزینه + سبز رنگ (و یا کلید insert کیبورد)، یک ردیف با مقادیر پیش فرض NULL (به معنی تهی) در ستون‌ها ایجاد می‌شود که آماده وارد کردن اطلاعات است:

اضافه کردن داده (ردیف) به جدول
اضافه کردن داده (ردیف) به جدول

ستون id را به صورت Auto increment تعیین کرده بودیم پس مقدار آن را همان null و دست نخورده باقی می‌گذارم و سراغ ستون‌های بعدی می‌روم. با کلید tab به راحتی می‌توانید بین ستون‌ها جابجا شوید و مقادیر را وارد کنید. من ۳ ردیف اطلاعات وارد کردم:

اضافه کردن سطر جدید به جدول

با Commit کردن تغییرات (گزینه تیک سبز رنگ) اطلاعات ثبت می شود:

ذخیره ردیف‌های جدول

حالا قصد دارم کوئری‌های اصلی و ضروری را روی این دیتابیس اجرا و تمرین کنم. کوئری‌های Insert، Update، Select و Delete.
در قدم اول تصمیم دارم مشخصات یک شخص را بجای استفاده از محیط گرافیکی، از طریق کوئری insert وارد جدول کنم. Syntax دستور insert به اینصورت است:

INSERT INTO table_name (column1, column2, column3,...columnN) VALUES (value1, value2, value3,...valueN);
سینتکس چیست: نحو یا Syntax به معنای نحوه نگارش و قرارگیری کلمات و عبارات به صورت درست، در یک زبان می‌باشد. در علم کامپیوتر، سینتکس یک زبان کامپیوتری، مجموعه‌ای از قوانین می‌باشد که نحوه قرارگیری و ترکیب کلمات، نشانه‌ها و علایم یک زبان را به صورتی که معنای درستی بدهند مشخص می‌کند. (به نقل از پارس‌دیتا)

مابین پرانتر ابتدایی نام ستون‌ها و در پرانتز دوم، بعد از VALUES (به معنی مقادیر)، مقادیر موردنظر را به ترتیب وارد می‌کنیم. به جای table_name نام دیتابیس جایگزین می‌شود.
با زدن گزینه Open SQL editor یا کلید میانبر (Alt + E) به برگه SQL Editor می‌روم:

SQL editor در SQLiteStudio
SQL editor در SQLiteStudio

کوئری زیر را وارد و توسط دکمه Execute query اجرا می‌کنم (execute به معنی اجرا است):

INSERT INTO person_details (id, name, family, age, tel) VALUES (NULL, 'Mohammad', 'Bustani', 29, '09154444444');
اجرای کوئری دیتابیس (Execute query)
اجرای کوئری دیتابیس (Execute query)

کوئری با موفقیت اجرا شد و پیغام Rows affected:1 نشان می‌دهد یک سطر دچار تغییر شده که در اینجا تغییر شامل اضافه شدن یک سطر بود:

لاگ کوئری

نکته: در کوئری id به صورت NULL وارد شد تا شناسه به صورت خودکار و افزایشی (Auto increment) به این ردیف اختصاص یابد.
نکته: تعداد فاصله بین کاراکترها، کوچک یا بزرگ بودن حروف و یک خطی/چند خطی بودن کوئری تاثیری در نتیجه ندارد. تنها کافی‌ست بین کلمات بدنه کوئری مانند INSERT و INTO یا VALUES و () حداقل یک فضای خالی وجود داشته باشد.
نکته: مقادیر رشته‌ای مانند TEXT و VARCHAR می بایست داخل ‘ ‘ (تک کوتیشن) قرار گیرد.

مجدد به جدول person_details برمی‌گردم (گزینه‌های پایین/سمت چپ نرم افزار امکان سوئیچ کردن بین SQL editor و دیتابیس را فراهم می‌کند). در برگه Data با بروزرسانی اطلاعات جدول توسط گزینه Refresh table data و یا کلید F5، ردیفی که به واسطه کوئری اضافه کرده بودم باید نمایش داده شود:

Refresh table data
به‌روزرسانی داده‌های وارد شده با Refresh table data

در تصویر زیر ردیف شماره ۴ داده‌های تعریف شده در کوئری را نمایش می‌دهد که با موفقیت به جدول اضافه شده:

کوئری INSERT
کوئری INSERT

کوئری بعدی که آزمایش می‌کنم Update هست.
Syntax کوئری Update:

UPDATE table_name SET column1 = value1, column2 = value2...., columnN = valueN WHERE [condition];

می خواهم نام شناسه ۳ را از SeyedMahdi به Sajad و سن را هم از ۳۳ به ۲۲ تغییر دهم. مجدد از طریق گزینه SQL Editor به بخش کوئری رفته و دستور زیر را وارد می کنم:

UPDATE person_details SET name = 'Sajad', age = 22 WHERE id = 3;

پس از اجرا مانند قسمت قبل در بخش Status پیغامی مبنی بر اینکه یک ردیف ویرایش شده چاپ شد:

کوئری UPDATE
کوئری UPDATE

به تب Data برمی‌گردم و اطلاعات جدول را بروز (Refresh) می‌کنم:

کوئری UPDATE

در تصویر بالا نام Sajad جایگزین SeyedMahdi در ردیف ۳ شده.
کوئری Select صرفاً برای انتخاب و نمایش ردیف‌هایی با مشخصاتی خاص بکار می‌رود و بر خلاف دو کوئری قبل، تغییری در جدول ایجاد نمی‌کند. به عنوان مثال می‌خواهم فقط نام خانوادگی افرادی نمایش داده شود که سن آنها ۳۰ سال و به بالا است.
Syntax کوئری Select به اینصورت است:

SELECT column1, column2, columnN FROM table_name WHERE [condition];

کوئری مدنظر من:

SELECT family FROM person_details WHERE age >= 30;

در دستور فوق، من ستون family ردیف‌هایی را فیلتر می‌کنم که ستون age آنها عددی بزرگتر یا مساوی با ۳۰ داشته باشد.
همانطور که در پاراگراف بالا اشاره شد، دستور Select صرفاً برای انتخاب اطلاعات است که این اطلاعات در همان تب SQL editor نمایش داده می‌شود:

کوئری SELECT
کوئری SELECT

در قسمت Grid view دو نام خانوادگی که شرط (condition) تعیین شده برای آنها صدق می‌کرد فیلتر شده است.
اگر بخواهم همه‌ی اطلاعات این افراد چاپ شده و صرفاً محدود به یک یا چند ستون نباشد، بجای ذکر نام ستون (مانند family در این مثال) کاراکتر * را جایگزین می‌کنیم. در سینتکس SQL کاراکتر * به معنی “همه” یا All است.
کوئری را به صورت زیر اصلاح و دوباره اجرا می‌کنم:

SELECT * FROM person_details WHERE age >= 30;
کاربرد کاراکتر * در SQL
کاربرد کاراکتر * در SQL

مشاهده می‌کنید برخلاف کوئری قبل، در Grid view تمامی اطلاعات دو شخصی که سن بالای ۳۰ سال داشتند نمایش داده شده.
و اما آخرین کوئری که در این قسمت بررسی می‌کنیم دستور DELETE است که مشخصاً برای حذف داده‌ها بکار می‌رود.
سینتکس کوئری Delete:

DELETE FROM table_name WHERE [condition];

به عنوان مثال می خواهم اطلاعات شخصی که با شناسه شماره ۲ در دیتابیس ثبت شده را حذف کنم:

DELETE FROM person_details WHERE id = 2;
کوئری DELETE
کوئری DELETE

در تصویر فوق، ردیف با شناسه (id) شماره ۲ حذف شده است.
فعلا در همین حد آشنایی با مبحث دیتابیس کافی‌ست. با این حال اگر مایل بودید اطلاعات بیشتری در این خصوص کسب کنید منابع متعددی از جمله وب‌سایت Tutorialspoint در دسترس هستند.
قبل از خروج از SQLiteStudio بهتر است چند دقیقه‌ای وقت گذاشته و با سایر گزینه‌ها و امکانات این نرم افزار و یا ابزار مشابهی که استفاده می‌کنید آشنا شوید. برای مثال با راست کلیک روی نام جدول و گزینه generate query for table به صورت خودکار چهار عمل اصلی که در بالا معرفی شد در قسمت Query editor برای شما آماده استفاده می‌باشد:

گزینه Generate query for table
گزینه Generate query for table

آموزش کار با SQLite در اندروید استودیو

نوبتی هم که باشد، نوبت آموزش دیتابیس SQLite در اندروید است. ابتدا طبق مبحث آموزش ساخت پروژه در اندروید استودیو یک پروژه اندرویدی با نام SQLite می‌سازم. اکتیویتی را از نوع Empty Activity و زبان را Java انتخاب کردم.
پروژه را در قالب یک اپلیکیشن کاربردی پیش می‌بریم. یک واحد تولیدی را در نظر می‌گیریم که تمامی کارمندان آن، یک شماره پرسنلی اختصاصی بر روی لباسشان درج شده و مدیر کارگاه قصد دارد روی موبایل اندرویدی خود، اپلیکیشنی داشته باشد که بتواند اطلاعات کامل کارکنان را ثبت و در مواقع لازم با وارد کردن کد پرسنلی درج شده بر روی لباس پرسنل، به مشخصات وی دسترسی داشته باشد.
البته مدنظرتان باشد این یک پروژه بسیار ساده و آموزشی است و به لحاظ طراحی و بهینه بودن کدها با یک اپلیکیشن کاربردی نهایی بسیار فاصله دارد. برای مثال من از مواردی مثل طراحی استاندارد ظاهر برنامه و رعایت حداکثری استانداردها در کدنویسی (مانند فرخوانی رشته‌های متنی از strings.xml و…) به جهت خلاصه شدن مبحث خودداری می‌کنم.

طراحی رابط کاربری

الان که در حال نگارش نسخه جدید این آموزش هستم (فروردین ۱۴۰۲)، از نگارش نسخه ابتدایی آن حدود ۷ سال می‌گذرد. در آن زمان هنوز لایه ConstraintLayout معرفی نشده بود و رابط کاربری اکتیویتی‌های اندروید عمدتاً با RelativeLayout و LinearLayout طراحی می‌شد.
رابط کاربری این آموزش نیز با RelativeLayout طراحی شده بود و از آنجایی که در این مبحث تمرکز ما روی دیتابیس SQLite هست، نیازی به طراحی مجدد این اکتیویتی با ConstraintLayout نمی‌بینم.
رابط کاربری اکتیویتی این پروژه به صورت زیر طراحی شده است:

رابط کاربری پروژه آموزش دیتابیس در اندروید
رابط کاربری پروژه آموزش دیتابیس در اندروید

در این Layout مجموعا ۷ عدد Widget بکار رفته که شامل ۳ ویجت TextView و ۴ ویجت Button است. سورس این لایه به اینصورت است:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="10dp"
    android:paddingLeft="10dp"
    android:paddingRight="10dp"
    android:paddingTop="10dp"
    tools:context=".MainActivity">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:ems="10"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:padding="10dp"
        android:id="@+id/edt_name"
        android:background="#E8E8E8"
        android:hint="نام" />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        android:ems="10"
        android:layout_below="@+id/edt_name"
        android:layout_marginTop="14dp"
        android:padding="10dp"
        android:id="@+id/edt_family"
        android:background="#E8E8E8"
        android:hint="نام خانوادگی" />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number"
        android:ems="10"
        android:layout_below="@+id/edt_family"
        android:layout_marginTop="14dp"
        android:padding="10dp"
        android:background="#E8E8E8"
        android:id="@+id/edt_id"
        android:hint="شناسه پرسنلی" />

    <Button
        android:text="ذخیره"
        android:textSize="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/edt_id"
        android:layout_marginTop="10dp"
        android:id="@+id/btn_insert" />

    <Button
        android:text="نمایش"
        android:textSize="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btn_insert"
        android:id="@+id/btn_view" />

    <Button
        android:text="بروزرسانی"
        android:textSize="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btn_view"
        android:id="@+id/btn_update" />

    <Button
        android:text="حذف"
        android:textSize="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btn_update"
        android:id="@+id/btn_delete" />

</RelativeLayout>

ویجت‌های TextView به ترتیب با idهای edt_name، edt_family، edt_id و ویجت‌های Button با btn_insert، btn_view، btn_update و btn_delete تعریف شده‌اند.
همیشه سعی کنید نامگذاری فایل‌ها، ویجت‌ها، کلاس‌ها و هرآنچه که در برنامه‌نویسی با آن سروکار دارید را با الگویی مشخص و بر اساس کاربرد آن انجام دهید تا توسعه پروژه با سرعت بالاتر و خطای کمتر پیش برود.
برای مثال هرکس بعداً سورس این پروژه را بررسی کند، با مشاهده ویجتی که با شناسه edt_family تعریف شده می‌تواند تشخیص دهد کاربرد آن مربوط به ویرایش نام خانوادگی است.

تکمیل کدهای اکتیویتی و کلاس دیتابیس

در قدم بعد در کلاس MainActivity.java به تعداد نیاز چند نمونه از کلاس‌های EditText و Button می‌سازم:

MainActivity.java

package ir.android_studio.sqlite;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

    EditText edtName, edtFamily, edtID;
    Button btnInsert, btnView, btnUpdate, btnDelete;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

برای ساخت آبجکت‌های هم نوع از یک کلاس (مانند EditText) به جهت کاهش حجم کد، آنها را به صورت جداگانه تعریف نکرده و تنها با یک کاما پشت سر هم قرار دادم. حالا درون متد onCreate هر کدام از نمونه‌ها را به ویجت (کامپوننت) مربوطه متصل می‌کنم:

MainActivity.java

package ir.android_studio.sqlite;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {

    EditText edtName, edtFamily, edtID;
    Button btnInsert, btnView, btnUpdate, btnDelete;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        edtName = findViewById(R.id.edt_name);
        edtFamily = findViewById(R.id.edt_family);
        edtID = findViewById(R.id.edt_id);
        btnInsert = findViewById(R.id.btn_insert);
        btnView = findViewById(R.id.btn_view);
        btnUpdate = findViewById(R.id.btn_update);
        btnDelete = findViewById(R.id.btn_delete);

    }
}

خب! فعلا کار ما با اکتیویتی تمام شد. حالا باید یک دیتابیس بسازیم، یک جدول درون دیتابیس ایجاد کنیم و متدهای مربوط به اَعمال ذخیره، نمایش، بروزرسانی و حذف اطلاعات را بنویسیم.
در اندروید یک کلاس کمکی با نام SQLiteOpenHelper وجود دارد که برای مدیریت دیتابیس بکار می‌رود. من یک کلاس جاوا با نام دلخواه DatabaseManager به پروژه اضافه می‌کنم. به این منظور درون پوشه java و روی نام پکیج (ir.android_studio.sqlite) راست کلیک کرده، گزینه New سپس Java Class و درون پنجره باز شده، نام کلاس را وارد می‌کنم:

کلاس مدیریت دیتابیس در اندروید
ساخت کلاس مدیریت دیتابیس

با وارد کردن نام کلاس و Enter، کلاس به پروژه اضافه می‌شود:

کلاس مدیریت دیتابیس در اندروید

کلاس DatabaseManager در اندروید

نکته: علاوه بر پوشه‌ مربوط به پکیج اصلی پروژه، دو پوشه دیگر همنام با پکیج وجود دارد که با پس‌زمینه رنگی مشخص شده و جلوی آنها دو عبارت androidTest و test داخل پرانتز قید شده است. ما با این پوشه‌ها کاری نداریم. برای جلوگیری از اشتباه بهتر است این دو پوشه test را از پروژه حذف کنید (انتخاب پوشه‌ها و Delete).
ممکن است در مرتبه اولی که پوشه‌ها را حذف می‌کنید، پوشه حذف نشده و به بالای پکیج اصلی منتقل شود. کافیست مجدد پوشه‌های تست را انتخاب کرده و Delete کنید. نتیجه به صورت زیر خواهد بود:

حذف پکیج‌های تست
حذف پکیج‌های تست
نکته: در هر قسمت از آموزش که در خواندن و تشخیص مکان قرارگیری کدها دچار مشکل شدید کدهای موجود در سورس ضمیمه شده آموزش را بررسی کنید. نیازی به ایمپورت کردن سورس در اندروید استودیو هم نیست.
می‌توانید فایل‌های پروژه را با ویرایشگر متنی ساده‌ای مثل Notepad++ باز کنید.

درحال حاضر کلاس ساخته شده به اینصورت است:

DatabaseManager.java

package ir.android_studio.sqlite;

public class DatabaseManager {

}

یک کلاس از نوع public که داخل بدنه (body) آن هیچ کدی وجود ندارد. برای مدیریت دیتابیس SQLite در اندروید کلاسی با نام SQLiteOpenHelper ازپیش ساخته شده که ما را از نوشتن کدهای اضافی بی‌نیاز می‌کند.
بنابراین در قدم اول باید کلاس DatabaseManager را از این کلاس ارث بری کنم. به‌عبارت‌دیگر باید آنرا از کلاس ذکر شده extends کنم:

استفاده از کلاس SQLiteOpenHelper در اندروید
استفاده از کلاس SQLiteOpenHelper

با تایپ کردن چند کاراکتر ابتدای کلاس، لیست پیشنهدات اندروید استودیو باز می‌شود و نیازی به تایپ کامل آن نیست. گزینه اول را انتخاب می‌کنم. کلاس SQLiteOpenHelper به اینصورت به کلاس اضافه شد:

DatabaseManager.java

package ir.android_studio.sqlite;

import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseManager extends SQLiteOpenHelper {

}

در خط دوم مشاهده می‌کنید کلاسی که ارث‌بری کردیم به‌صورت خودکار import شده است. چنانچه این ایمپورت خودکار انجام نشد، ارور Cannot resolve symbol ‘SQLiteOpenHelper’ نمایش داده می‌شود. با کلیک روی نام کلاس و کلیدهای Alt+Enter ایمپورت انجام می‌شود:

رفع خطای ایمپورت SQLiteOpenHelper
رفع خطای ایمپورت SQLiteOpenHelper

مطابق تصویر زیر اگر همزمان ctrl را نگه داشته و روی نام آن کلیک کنم، کلاس باز شده و می‌توانید محتوای داخل آن را بررسی کنید:

مشاهده سورس کلاس SQLiteOpenHelper

مشاهده سورس کلاس SQLiteOpenHelper

چنانچه برای اولین مرتبه قصد باز کردن کلاس‌های اندروید را داشته باشید پیغامی نمایش داده می‌شود که با انتخاب گزینه Access مجوز دسترسی به کلاس‌ها را دریافت می‌کنید.
با نگه داشتن موس روی تب کلاس، محل قرارگیری کلاس نمایش داده می‌شود. همانطور که در تصویر بالا مشاهده می‌کنید، فایل این کلاس در پوشه android-13 قرار گرفته که مربوط به API 33 است.
درحال‌حاضر کلاس DatabaseManager یک زیرکلاس (Subclass) از SQLiteOpenHelper محسوب می‌شود.
یک ارور داخل کلاس وجود دارد. با بردن نشانگر موس روی بدنه کلاس، متن ارور نمایش داده می‌شود:

اضافه کردن متدهای SQLiteOpenHelper
اضافه کردن متدهای SQLiteOpenHelper

در متن خطا قید شده که متد onCreate مربوط به کلاس SQLiteOpenHelper باید اضافه یا implement شود. با کلیک روی Implement methods یا Alt+Shift+Enter متد مربوطه به کلاس اضافه می‌شود.
البته چنانچه روی بدنه کلاس کلیک کرده باشید، آیکون لامپ ظاهر می‌شود که از طریق این آیکون نیز می‌توان عمل implement را انجام داد:

implement کردن متدهای SQLiteOpenHelper

پس از انتخاب گزینه implement method در هریک از دو روش فوق، پنجره زیر باز می‌شود که ۲ متد را برای اضافه کردن نشان می‌دهد:

ایمپلیمنت کردن متدهای SQLiteOpenHelper

در این پنجره دو متد onCreate و onUpgrade وجود دارد که به صورت پیش فرض هردو انتخاب شده و من هر دو را تایید می کنم. با انجام این کار، این متدها به کلاس اضافه شد:

DatabaseManager.java

package ir.android_studio.sqlite;

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseManager extends SQLiteOpenHelper {

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}

دو متد با پارامتر ورودی SQLiteDatabase و نام sqLiteDatabase داخل کلاس ایمپلیمنت شد. متد onCreate برای ساخت جدول دیتابیس و متد onUpgrade برای بروزرسانی ساختار جدول (حذف یا اضافه کردن ستون) بکار می‌رود.
اما بعد از اضافه شدن این دو متد یک خطای دیگر نمایش داده می‌شود:

افزودن متد سازنده کلاس دیتابیس
افزودن متد سازنده کلاس دیتابیس

There is no default constructor available in ‘android.database.sqlite.SQLiteOpenHelper’

یعنی کلاسی که از SQLiteOpenHelper مشتق (ارث بری) شده، علاوه بر دو متد فوق، به یک سازنده (Constructor) نیز نیاز دارد که عمل ایجاد فایل دیتابیس توسط سازنده صورت می‌گیرد:

افزودن متد سازنده کلاس دیتابیس

در پنجره بازشده، متد سازنده اول انتخاب شده که بدون تغییر آن، تایید می‌کنم. دو مورد دیگر مربوط به مدیریت ارورها (error handler) هستند که در اینجا نیازی نداریم. متد سازنده به کلاس اضافه می‌شود:

DatabaseManager.java

package ir.android_studio.sqlite;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import androidx.annotation.Nullable;

public class DatabaseManager extends SQLiteOpenHelper {

    public DatabaseManager(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}

متد سازنده همیشه همنام با کلاس خودش است. من سعی می‌کنم نامگذاری‌های پیش فرض را تغییر دهم و همچنین در هر متد از نام‌های متفاوتی استفاده کنم تا کمتر باعث سردرگمی شما شود. اما مسلما زمانی که کدها را درک کردید، نیازی نیست در نامگذاری‌ها وسواس بخرج دهید. به عنوان مثال نام پارامتر Context را از context به cnt تغییر می‌دهم.

جهت مطالعه ادامه آموزش، فایل PDF را دانلود نمائید

توجه : سورس پروژه درون پوشه Exercises قرار دارد

با توجه به اینکه آموزش‌های پایه با قیمت پایین در اختیار کاربر قرار گرفته و درآمد حاصل صرف تامین هزینه‌های وب سایت و تهیه آموزش‌های آتی می‌شود، به اشتراک گذاری این فایل با دیگران خلاف اخلاق است.

دانلود نسخه کامل این آموزش به همراه سورس پروژه
تعداد صفحات : ۸۴
حجم : ۴ مگابایت
قیمت : ۴۶ هزار تومان
تاریخ بروزرسانی آموزش : ۱۴۰۲/۰۱/۲۳
توجه: صرفا در صورتی از درگاه پشتیبان استفاده کنید که قادر به پرداخت از طریق سبد دانلود نباشید.
افزودن به سبد دانلود درگاه پشتیبان
برچسب ها :
این مطلب چقدر برایتان مفید بود؟ لطفا امتیاز دهید
4.4/5 - (35 امتیاز)
پرسش‌ها و دیدگاه‌های کاربران
دوره آموزش برنامه نویسی اندروید
دوره آموزش برنامه نویسی اندروید

با دریافت این دوره به تمامی آموزش‌های غیر رایگان و رایگان موجود در وب سایت دسترسی دارید که تخفیفی برای آموزش‌های غیر رایگان نیز درنظر گرفته شده. این پکیج به دو صورت دانلودی و ارسال پستی ارائه می‌گردد.
آموزش‌های اندروید استودیو در دو دسته «پایه» و «تکمیلی» منتشر می‌شوند.
آموزش‌های پایه شامل مباحث اصلی و ضروری و آموزش‌های تکمیلی مطالبی است که می‌بایست در کنار مطالب اصلی بررسی شود.
با خرید این دوره، به تمامی آموزش‌های غیر رایگانی که در آینده منتشر می‌شود نیز به صورت رایگان دسترسی خواهید داشت!

یک دیدگاه بنویسید

پرسش‌های زیر تایید و پاسخ داده نـــخواهند شد:
۱: جزء موارد مطرح شده در صفحات مشکلات و پرسش‌های رایج و بروزرسانی‌های محتوای آموزشی باشد
۲: سوال قبلا توسط کاربران در دیدگاه‌ها مطرح و پاسخ داده شده باشد
۳: پرسش خارج از مبحث آموزشی موجود در این صفحه باشد