آموزش کار با دیتابیس در اندروید استودیو
با نام و یاد خدا
در این جلسه قصد داریم به آموزش کار با دیتابیس در اندروید استودیو بپردازیم. در هر برنامه یا اپلیکیشنی یک سری داده یا اطلاعات ایجاد می شود که ذخیره آن داده ها به صورت منظم برای استفاده در آینده بسیار مهم می باشد.
اساسی ترین روش برای ذخیره داده ها استفاده از پایگاه داده یا دیتابیس(database) می باشد.
تعریف دیتابیس:
به مجموعه ای از داده ها که در ساختار منظمی داخل جداول ذخیره می شوند، دیتابیس گویند. این اطلاعات توسط سیستم مدیریت پایگاه داده (DBMS)، قابل دسترسی ، به روز رسانی و حذف می باشد.
حالا می خواهیم با روش استفاده از دیتابیس در اندروید آشنا شویم. یعنی چگونه دیتابیس بسازیم؟ جدول بسازیم؟ چگونه اطلاعات را وارد کنیم؟و … در این جلسه فقط به ایجاد دیتابیس و جدول و به روز رسانی دیتابیس می پردازیم و در جلسات بعد نحوه اضافه کردن اطلاعات، به روزرسانی اطلاعات و حذف اطلاعات را آموزش می دهیم.
ایجاد پروژه
- خب ابتدا یک پروژه جدید با نام دلخواه myDatabase ایجاد می کنیم.(طبق آموزش جلسه ششم)
- به غیر از کلاس MainActivity ،یک کلاس جدید می سازیم با نام دلخواه myDatabaseHelper.نکته: می خواهیم در این کلاس عملیات ایجاد پایگاه داده، جدول، متدهای اضافه کردن اطلاعات، به روز رسانی و حذف اطلاعات و … را تعریف کنیم. و در هر جای برنامه که نیاز بود، این کلاس را فراخوانی کنیم.(طبق آموزش شی گرایی)
برای ایجاد کلاس از قسمت app->java روی پوشه اول راست کلیک کنید و New -> javaClass را انتخاب کنید. در پنجره باز شده نام کلاس را انتخاب می کنیم.
- بعد از ایجاد کلاس myDatabaseHelper نیاز داریم تا این کلاس از SQLiteOpenHelper، اکستند شود. یعنی ارث بری کند و به تمام خصوصیات و متدهای این کلاس دسترسی داشته باشد. برای این کار از کلمه کلیدی extends استفاده می کنیم:
public class myDatabaseHelper extends SQLiteOpenHelper{
}
SQLiteOpenHelper: یک کلاس کمکی برای ایجاد دیتابیس و مدیریت آن می باشد که در اندروید استودیو تعریف شده و ما به راحتی از این کلاس ارث بری می کنیم.
- حالا نیاز داریم متدهای مورد نیاز برای کلاس myDatabaseHelper تعریف کنیم. بعد از ارث بری از SQLite باید ۳ متد اصلی در این کلاس تعریف شود.
تعریف متدها
- برای تعریف توابع داخل کلاس راست کلیک می کنیم و گزینه Generate را انتخاب می کنیم. در کادر ظاهر شده گزینه Override Methods را انتخاب می کنیم.
- در پنجره باز شده لیستی از توابعی که در کلاس SQLiteOpenHelper وجود دارد را نمایش می دهد. ما باید کلاس های مورد نیاز خود را انتخاب کنیم .
- تابع سازنده کلاس SQLiteOpenHelper و توابع onCreate و onUpgrade را انتخاب می کنیم و ok را می زنیم تا پیاده سازی شوند.
- داخل کلاس و بیرون از متدها یک متغیر برای دیتابیس با نام دلخواه DB_NAME و یک متغیر برای جدول با نام دلخواه TBL_NAME تعریف می کنیم:
public static final String DB_NAME=“uni.db”;
public static final String TBL_NAME=“stu”;
تابع سازنده
تابعی که هم نام با نام کلاس می باشد، تابع سازنده است. ابتدا طبق تصویر بالا تمام ورودی ها به غیر از Context را پاک می کنیم. در واقع وقتی شی ای از این کلاس ساخته می شود، تابع سازنده اولین تابعی است که اجرا می شود.
در تابع سازنده، خود تابع سازنده کلاس پدر را با کلمه کلیدی Super فراخوانی می کند. ورودی های super را هم به شکل زیر تعریف می کنیم. name را متغیر دیتابیس ، factory هم null و version دیتابیس هم 1 قرار می دهیم.
public myDatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);
}
تابع onCreate
در این تابع ما ساختار جدول ها را تعریف می کنیم.
به عنوان ورودی یک دیتابیس با نام db و از نوع SQLiteDatabase دریافت می کند و با متد execSQL دستورات sql را اجرا می کند.
توضیح کد زیر: در کد زیر گفته شده یک جدول ایجاد شود با نام stu و ستون یا فیلدهای آن Id و name و lastname باشد.
نکته: حروف کوچک و بزرگ رعایت شود.
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(” CREATE TABLE ” + TBL_NAME + “(Id INTEGER PRIMARY KEY AutoIncrement , name TEXT , LastName TEXT)”);
}
تابع onUpgrade
توجه داشته باشید این تابع مربوط به، به روز رسانی و تغییر ساختار دیتابیس می باشد (در جلسات آتی یک تابع update مربوط به ، به روزرسانی اطلاعات جدول آموزش می دهیم)
کاربرد این تابع به این صورت است که اگر تصمیم بگیریم یک ستون جدید به جدول اضافه کنیم یا هر تغییر در ساختار ، باید تغییرات را در این تابع تعریف کنیم. و با اجرای این تابع تغییرات اعمال شود.
نکته:حواستون باشه که اطلاعات قبلی پاک می شوند. پس قبل از تغییر به فکر بک آپ باشید.
توضیح کد: دوباره با استفاده از متد execSQL دستورات SQL را اجرا می کنیم. در این دستور می گوییم اگر جدولی با نام TBL_NAME وجود دارد را پاک کن و جدول با ساختار جدید که در تابع onCreate تعریف شده است را مجدد اجرا کن.
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(” DROP TABLE IF EXISTS ” + TBL_NAME);
onCreate(db);
}
- یک خط کد در تابع سازنده اضافه می کنیم که پایگاه داده db را قابل نوشتن می کند(نکته: فعلا این خط کد را اینجا اضافه کنید تا در جلسه بعد در جای اصلی خودش قرار بدهیم )
SQLiteDatabase db=this.getWritableDatabase();
کدهای کلاس myDatabaseHelper به صورت کامل
خب تا اینجا کدهای داخل کلاس myDatabaseHelper به این صورت است:
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class myDatabaseHelper extends SQLiteOpenHelper{
public static final String DB_NAME=“uni.db”;
public static final String TBL_NAME=“stu”;
//تابع سازنده
public myDatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);
SQLiteDatabase db=this.getWritableDatabase();
}
//تابع onCreate
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(” CREATE TABLE ” + TBL_NAME + “(Id INTEGER PRIMARY KEY AutoIncrement , name TEXT , LastName TEXT)”);
}
//تابع به روزرسانی
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(” DROP TABLE IF EXISTS ” + TBL_NAME);
onCreate(db);
}
}
فراخوانی کلاس myDatabaseHelper
- حالا باید کلاسی(myDatabaseHelper ) که ایجاد کردیم را در MainActivity فراخوانی کنیم. برای این کار باید از کلاس myDatabaseHelper شی بسازیم:
داخل کلاس و بیرون توابع یک متغیر با نام دلخواه mydb از نوع myDatabaseHelper تعریف می کنیم:
myDatabaseHelper mydb;
سپس داخل متد onCreateشی را ایجاد می کنیم:
کلاس myDatabaseHelper یک ورودی به نام context می خواهد که به جای آن مقدار this را قرار می دهیم.
mydb=new myDatabaseHelper(this);
- حالا برنامه را اجرا کنید(ما از Genymotion برای اجرای برنامه استفاده می کنیم).
- در حالی که برنامه در حال اجرا است، در قسمت کناری سمت راست اندروید استودیو گزینه Device File Explorer را انتخاب کنید و دستگاه خود را انتخاب کنید . بعد data->data را انتخاب کنید تا لیستی از پروژه ها نمایش داده شود. پروژه خود را انتخاب کنید:
همانطور که در تصویر می بینید پایگاه داده با نام uni ایجاد شده است.شما می توانید این دیتابیس را ذخیره و در نرم افزار Navicate باز کنید.
امیدواریم از آموزش کار با دیتابیس در اندروید استودیو استفاده برده باشید. در جلسه بعد به نحوه اضافه کردن اطلاعات به جدول می پردازیم.
لطفا سوالات و پیشنهادات خود را در قسمت دیدگاه ها با در میان بگذارید.
سلام
خداقوت دمتون گرم یه مشکل بزرگی رو از بنده حل کردید.
ان شاالله عاقبت به خیر شید.
سلام وقت بخیر
ساخت جدول مشترک به چه صورتی هست
من میخوام ۲ تا جدول دارم میخوام بگم وقتی fav=1 شد اون سطر رو کپی کن تو جدول مشترک
جدول مشترک رو دقیقا مثل اون ۲ تا جدول ساختم با همون فیلد هایی که داخلشه
database.execSQL(“UPDATE data set fav = 1 WHERE id =” + id);
database.execSQL(“INSERT INTO favorite SELECT * FROM data WHERE fav = 1”);
از این کد استفاده کردم favorite اسم جدول مشترکمه
ولی جواب نمیده اولین سطر کپی میشه ولی برای سطر بعدی کرش میکنه و این خطا رو میده
UNIQUE constraint failed: favorite.id (code 1555
تو قست ساخت جدول تیک های یونیک و آوتو اینکریمنت و .. اینا رو برداشتم و درست شد ولی به جاش تو جدول مشترک ۵ یا ۶ بار کپی میشه !!!
ممنون میشم راهنمایی کنید یک هفته میشه درگیرشم :(
سلام و عرض ادب.
لطفا به primary key بودن فیلد توجه کنید.
سلام هر دو جدول pirmary key هم بودن , فیلد id به عنوان primary key انتخاب شده بود که همین مشکل رو داشتم
سلام ، مطابق آموزش پیش رفتم ، ولی وقتی میخوام از کلاس myDatabaseHelper شی درست کنم خطا میگیره و کلاس رو نمیشناسه !!
سلام و احترام
کلاس myDatabaseHelper درست ایجاد نشده است. لطفا مجدد طبق آموزش کلاس را ایجاد کنید اگر مشکل حل نشد خطایی که مشاهده می کنید به صورت دقیق ارسال کنید.
با تشکر از همراهی شما
احتمالا دارید با زبان kotlin می نویسید
وقت شروع پروژه از قسمت انتخاب زبان Jjava را انتخاب کنید درست میشه
سلام خسته نباشید
من زمان اجرا این خطا رو دارم:
Unable to start activity ComponentInfo{com.example.tickeno/com.example.tickeno.MainActivity}: java.lang.IllegalStateException: getDatabase called recursively
این خطا رو خیلی سرچ کردم اما جواب نگرفتم.
این بخشی از کلاس منیجر دیتابیسم هست:
@Override
public void onCreate(SQLiteDatabase db) {
updateMyDatabase(db, 0, DB_VERSION);
}
private static void updateMyDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion < ۱) {
String query = "CREATE TABLE " + tblTask + "(" + task_Id + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ title + " TEXT,"
+ categoryId + " INTEGER,"
+ priorityId + " INTEGER);";
db.execSQL(query);
}
}
public void insertTask(TaskModel task) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues taskValues = new ContentValues();
taskValues.put(title, task.title);
taskValues.put(categoryId, task.categoryId);
taskValues.put(priorityId, task.priorityId);
db.insert(tblTask, null, taskValues);
db.close();
}
جاییکه در MainActivity تابع insertTask صدا زده شده:
TaskModel task = new TaskModel(0,txtTaskTitle,1,1);
tickDatabaseHelper.insertTask(task);
سلام و عرض ادب. بهتر است ابتدا تابع به تابع را غیرفعال کنید و اجرا بگیرید تا برنامه به قسمت های کوچکتر تقسیم بشه که راحت تر بتوانید عیب یابی کنید. دوما به نظر من کلمه static در تابع private static void updateMyDatabase اضافی هست و نیاز به نوشتن static نیست. سوما چون بخشی از برنامه ارسال شده راهنمایی کردن شما مشکل هست. در صورتی که با این راهنمایی ها مشکل حل نشد لطفا با شماره ۰۹۱۰۳۸۲۳۲۵۳ در ساعت اداری هماهنگ کنید تا به صورت ریموتی مشکل شما بررسی شود.
با تشکر از همراهی شما
ممنون از پاسخگوییتون
فعلا با این لینک مشکل حل شد
https://stackoverflow.com/questions/56264766/android-getdatabase-called-recursively-error
باز هم سپاس
سایتتون عالیه
آموزش های درست و اصولی و کاربردی دارین
واقعا ممنونم
یه مشکل مهم منو حل کردید.
امیدروارم همیشه موفق باشید و همینجور با قدرت ادامه بدید .
سلام
اگر بخواهیم داخل دیتابیس فایل(مثلا ورد) ذخیر ه کنیم و داخل لایه نمایشش و ویرایش کنیم ؟؟
آیا راه حلی وجود دارد؟
سلام و عرض ادب. برای ذخیره فایل بهترین راه ذخیره آدرس در دیتابیس هست و فایل را از آدرس آن فرخوانی کنید.
با تشکر از همراهی شما
سلام من با استفاده از دیتا بیس اکسترنال یک دیتا بیس درست کردم وامدم داخل برنامه اندروید استودیو دیتا بیس رو به اندرویداستودیو وصل کردم و شرطی گذاشتم که دیتا بیس موجوده یا نه
public Listgetallperson(){
SQLiteDatabase db=this.getReadableDatabase();
Listdata =new ArrayList();
String query=”SELECT * FROM person”;
Cursor cursor=db.rawQuery(query,null);
if (cursor.moveToFirst()){
do {
person person=new person();
person.setId(cursor.getInt(cursor.getColumnIndex(info_db.DATA_ID)));
person.setCategory(cursor.getString(cursor.getColumnIndex(info_db.DATA_CATEGORY)));
person.setName(cursor.getString(cursor.getColumnIndex(info_db.DATA_NAME)));
person.setFiled(cursor.getString(cursor.getColumnIndex(info_db.DATA_FILED)));
person.setDisc(cursor.getString(cursor.getColumnIndex(info_db.DATA_DISC)));
person.setImg(cursor.getString(cursor.getColumnIndex(info_db.DATA_IMG)));
person.setNav(cursor.getInt(cursor.getColumnIndex(String.valueOf(info_db.DATA_NAV))));
}while (cursor.moveToNext());
}
cursor.close();
db.close();
return data;
}
به خط Cursor خطا میگیره و برنامه اجرا و بسته میشود
اگه کدهای بالا رو متوجه نشدید من یک عکس از این کدهام گرفتم و داخل لینک پایین قرار دادم
http://s6.picofile.com/file/8387530242/Sketch.png
سلام و عرض ادب.
لطفا لینک زیر را مطالعه نمایید:
https://www.programcreek.com/java-api-examples/android.database.Cursor
با تشکر از همراهی شما
خیلی ممنون از آموزش جامع و خوبتون ، انشاالله که همیشه تنتون سلامت باشه
سلام و عرض خدا قوت خدمت شما
و همچنین بابت آموزش های بسیار روان شما مهندس عزیز
سوالم اینه که چطور به سطون های جول اضافه کنم مثلا شماره دانشجویی و آدرس ایمیل و …
با تشکر
سلام و عرض ادب. مانند ستون نام و نام خانوادگی شما می توانید ستون های دیگری نیز اضافه نمایید.
با تشکر از همراهی شما
با عرض سلام و خداقوت بابت آموزش های بی نظیرتون . در این قسمت وقتی دیتابیس رو ذخیره کنیم و در نرم افزار navicat باز کنیم باید چه چیزی مشاهده کنیم ؟ باید جدول را به ضورت منظم و با نام ستون هایش ببینیم؟ چون من وقتی باز می کنم یک سری حروف درهم میبینم صرفا . سپاس
سلام وقتتون بخیر من چجور میتونم داخل sqlite ادرس عکس رو دخیره کنم و در ریسایکلر ویو اون عکس رو نمایش بدم
سلام و عرض ادب
خواستم بپرسم که SQLiteOpenHelper فقط برای دیتابیس های SQLite هستند یا برای MYSQL هم کاربرد دارند
سلام و عرض ادب. در مقاله مرجع اندروید استدیو فقط برای استفاده Sqlite می باشد و اشاره ای به پایگاه داده Mysql نشده است.
با تشکر از همراهی شما
سلام
من از چنتا recycleviewer در پروژم استفاده کردم ولی زمانی که اجرا میگیرم جای اینکه داده هامو همه رو نشون بده فقط اولی رو نشون میده و اگر حذفش کنم تازه دومی رو نشون میده
میخواستم بدونم مشکل از کجاست
ممنونم
سلام من تمام مراحل رو انجام دادم اما پوشه دیتا بیس ایجاد نمیشه مشکل چیه
سلام اگه فایل جدید ایجاد کنیم کجا ذخیره میشه؟
اگه بخوایم فایل قبلی رو باز کنیم تو چه آدرسی باید قرار بدیم؟
با سپاس از شما بابت این آموزش مفید.
یک سوال داشتم ، اگر بخواهیم دیتابیس برنامه اندرویدی بر روی یک هاست یا بر روی گوگل درایو کاربر ذخیره شود از چه روشی باید استفاده کنیم. حداقل توضیحی هم کمک میکنه تا بتونم سرچ کنم. چون هرچه جستجو میکنم همین مطالب فقط میاد.
پ.ن: مثلا اطلاعات اپلیکیشن دفترچه یادداشت بر روی گوگل درایو یا سایتی ذخیره شوند تا اگر کاربر برنامه را پاک کرد و دوباره نصب کرد با ورود نام کاربری دوباره آن اطلاعات قبل را داشته باشد.
سپاسگزارم