آموزش دیتابیس Room در اندروید
سلام توسعه دهندگان گرامی در این سری از آموزش برنامه نویسی اندروید به آموزش دیتابیس Room در اندروید می پردازیم قبلا دیتابیس جدید گوگل (Room Persistence Library) را به شما معرفی کردیم در این آموزش نحوه استفاده از Room Persistence Library را برای شما قرار میدهیم در ادامه با ما همراه باشید.
Room Persistence Library چیست ؟
وارد فایل build.gradle شده و در بخش dependencies دو خط زیر را قرار دهید.
1 2 | implementation "android.arch.persistence.room:runtime:1.1.1" annotationProcessor "android.arch.persistence.room:compiler:1.1.1" |
دو خط بالا کتابخانه room را به پروژه شما اضافه می کند قندشکن فراموش نشود منتظر بمانید پروژه sync شود.
در ابتدای کار باید یک کلاس به نام User ایجاد کنید این کلاس نام دیتابیس و ستون های ما را شامل خواهد شد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | @Entity(tableName = "user") public class User { @PrimaryKey(autoGenerate = true) private int uid; @ColumnInfo(name = "first_name") private String firstName; @ColumnInfo(name = "last_name") private String lastName; @ColumnInfo(name = "age") private int age; public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } |
از واژه @Entity به منظور تعیین نام table استفاده کردیم برای اینکه یک فیلد را PrimaryKey کنیم کافی است از annotation آن استفاده کنیم اگر بخواهیم آن را به صورت autoGenerate تعیین کنیم کافی است مقدار آن را برابر با true قرار دهیم و در نهایت برای تعریف ستون از واژه ColumnInfo استفاده می کنیم در واقع کلاس بالا یک نوع Getter/Setter است که با دادن مقادیر داده ها در ستون های مشخص شده با annotation قرار می گیرند.(این کلاس شامل نام دیتابیس و فیلد ها یا ستون های آن بود)
باید یک Interface ایجاد کنید تا عمل query زدن در آن انجام شود به interface (در کاربر) Dao گفته می شود که شامل چهار annotation به نام های @Query, @Insert, @Update, @Delete برای انجام عملیات CRUD (درج جذف آپدیت و خواندن) استفاده می شود.
یک Interface به نام UserDao ایجاد کرده و کدهای زیر را در آن قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 | @Dao public interface UserDao { @Query("SELECT * FROM user") List<User> getAll(); @Query("SELECT * FROM user where first_name LIKE :firstName AND last_name LIKE :lastName") User findByName(String firstName, String lastName); @Query("SELECT COUNT(*) from user") int countUsers(); @Insert void insertAll(User... users); @Delete void delete(User user); } |
اگر دقت کنید Query زدن در بالا انجام شده است.
در نهایت باید یک کلاس به نام AppDatabase.class ایجاد کنید این فایل نگهدارنده دیتابیس یا Database Holder است ارتباط بین Interface و Getter/Setter توسط این کلاس انجام می شود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { private static AppDatabase INSTANCE; public abstract UserDao userDao(); public static AppDatabase getAppDatabase(Context context) { if (INSTANCE == null) { INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "user-database") .allowMainThreadQueries() .build(); } return INSTANCE; } public static void destroyInstance() { INSTANCE = null; } } |
در اینجا نام فایل دیتابیس رو مشخص کردیم و کلاس ها را بهم ارتباط دادیم.
یک کلاس کمکی ایجاد می کنیم تا یکسری داده تست در دیتابیس درج کنیم نام این فایل برابر با DatabaseInitializer.java است و کدهای زیر را در آن قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import android.os.AsyncTask; import android.support.annotation.NonNull; import android.util.Log; import com.nagarro.persistence.database.AppDatabase; import com.nagarro.persistence.entity.User; import java.util.List; public class DatabaseInitializer { private static final String TAG = DatabaseInitializer.class.getName(); public static void populateAsync(@NonNull final AppDatabase db) { PopulateDbAsync task = new PopulateDbAsync(db); task.execute(); } public static void populateSync(@NonNull final AppDatabase db) { populateWithTestData(db); } private static User addUser(final AppDatabase db, User user) { db.userDao().insertAll(user); return user; } private static void populateWithTestData(AppDatabase db) { User user = new User(); user.setFirstName("Ajay"); user.setLastName("Saini"); user.setAge(25); addUser(db, user); List<User> userList = db.userDao().getAll(); Log.d(DatabaseInitializer.TAG, "Rows Count: " + userList.size()); } private static class PopulateDbAsync extends AsyncTask<Void, Void, Void> { private final AppDatabase mDb; PopulateDbAsync(AppDatabase db) { mDb = db; } @Override protected Void doInBackground(final Void... params) { populateWithTestData(mDb); return null; } } } |
و در نهایت در اکتیویتی از کد زیر استفاده کنید.
1 | DatabaseInitializer.populateAsync(AppDatabase.getAppDatabase(this)) |
این آموزش هم به پایان رسید.
موفق و پیروز باشید.
سلام من با دیتابیس Room کار میکنم
تو کوئری زدن واسه جستجو کردن ب مشکل خوردم
955 تا سطر تو دیتابیس دارم اگه بخوام مثلا بخوام علی نذری رو جستجو کنم
955 تا علی نذری بر میگردونه یعنی همش تکراری دو تا کوئری زدم ب این شکل ایا مشکلی داره؟
@Query(“SELECT * FROM advari WHERE C LIKE ‘%’ || :search|| ‘%’ “)
fun search_frosh(search: String): List
@Query(“SELECT * FROM advari WHERE C =:search “)
fun search_frosh(search: String): List
کد زیر رو بررسی کنید.
@Query(“SELECT * FROM DealInfo WHERE deal LIKE :dealText LIMIT 1 “)
public LiveData
> getDealsList(String dealText);
موفق و پیروز باشید.
Async task در این کد چیکار می کنه ؟ به دیتابیس room ربطی داره یا همون بحث ارتباط با سروره که داده ها رو از سرور می گیره؟
سلام کوئری زدن عمل زمان بری محسوب میشه و بهتره خارج از Main Thread انجام بشه (در یک ترد جدید) و Async Task هم همون ترد جدید هست که این کار رو برامون می کنه در روم ربطی به سرور نداره.
اینکه معمولا Async Task رو همراه ارتباط با سرور میبینیم عملیات ریکوئست و ریسپانس هم عمل زمان بری هستن
در کل هرجا از Async Task استفاده میشه یعنی عمل زمان بری در حال انجامه که نباید در Main Thread انجام بشه که یوآی بلاک نشه و اپمون تجربه کاربری بدی نداشته باشه 🙂
سلام خسته نباشید
من وقتی اون دو خط رو به build.gradle اضافه میکنم و سینک میکنم ارور میده
میشه راهنماییم کنید؟
برا اینکه خطا نده نیازه از چیز شکن استفاده کنید.
خیلی ممنون بابت آموزش خوبتون توضیحاتتون ساده و کامل بود
سلام من دقیقا طبق اموزشتون پیش رفتم ولی وقتی میخوام از دیتاها استفاده کنم و اونارو توی تکست ویو ست کنم برنامه کرش میکنه.راهی هست بتونم دیتاهارو توی ترد دیگه ای بگیرم و موقع ست کردن بیارم توی ترد اصلی؟