অ্যান্ড্রয়েড জেটপ্যাকের রুম অংশ ব্যবহার করে স্থানীয় ডেটাবেসে ডেটা সংরক্ষণ করুন।
যেসব অ্যাপ উল্লেখযোগ্য পরিমাণে কাঠামোগত ডেটা নিয়ে কাজ করে, তারা সেই ডেটা স্থানীয়ভাবে সংরক্ষণ করলে ব্যাপকভাবে উপকৃত হতে পারে। এর সবচেয়ে সাধারণ ব্যবহার হলো প্রাসঙ্গিক ডেটা ক্যাশ করে রাখা, যাতে ডিভাইসটি নেটওয়ার্ক অ্যাক্সেস করতে না পারলেও ব্যবহারকারী অফলাইনে থাকা অবস্থায় সেই কন্টেন্ট ব্রাউজ করতে পারেন।
Room পার্সিস্টেন্স লাইব্রেরিটি SQLite-এর উপর একটি অ্যাবস্ট্রাকশন লেয়ার প্রদান করে, যা SQLite-এর সম্পূর্ণ শক্তিকে কাজে লাগানোর পাশাপাশি সাবলীলভাবে ডেটাবেস অ্যাক্সেস করতে দেয়। বিশেষত, Room নিম্নলিখিত সুবিধাগুলো প্রদান করে:
- SQL কোয়েরিগুলোর কম্পাইল-টাইম যাচাইকরণ।
- সুবিধাজনক টীকা যা পুনরাবৃত্তিমূলক এবং ত্রুটিপ্রবণ বয়লারপ্লেট কোড হ্রাস করে।
- সুবিন্যস্ত ডাটাবেস মাইগ্রেশন পথ।
এইসব বিবেচনার কারণে, আমরা আপনাকে সরাসরি SQLite API ব্যবহার না করে Room ব্যবহার করার জন্য দৃঢ়ভাবে সুপারিশ করছি।
সেটআপ
আপনার অ্যাপে Room ব্যবহার করতে, আপনার অ্যাপের build.gradle ফাইলে নিম্নলিখিত ডিপেন্ডেন্সিগুলো যোগ করুন।
কোটলিন
dependencies { val room_version = "2.8.4" implementation("androidx.room:room-runtime:$room_version") // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP) // See Add the KSP plugin to your project ksp("androidx.room:room-compiler:$room_version") // If this project only uses Java source, use the Java annotationProcessor // No additional plugins are necessary annotationProcessor("androidx.room:room-compiler:$room_version") // optional - Kotlin Extensions and Coroutines support for Room implementation("androidx.room:room-ktx:$room_version") // optional - RxJava2 support for Room implementation("androidx.room:room-rxjava2:$room_version") // optional - RxJava3 support for Room implementation("androidx.room:room-rxjava3:$room_version") // optional - Guava support for Room, including Optional and ListenableFuture implementation("androidx.room:room-guava:$room_version") // optional - Test helpers testImplementation("androidx.room:room-testing:$room_version") // optional - Paging 3 Integration implementation("androidx.room:room-paging:$room_version") }
গ্রোভি
dependencies { def room_version = "2.8.4" implementation "androidx.room:room-runtime:$room_version" // If this project uses any Kotlin source, use Kotlin Symbol Processing (KSP) // See KSP Quickstart to add KSP to your build ksp "androidx.room:room-compiler:$room_version" // If this project only uses Java source, use the Java annotationProcessor // No additional plugins are necessary annotationProcessor "androidx.room:room-compiler:$room_version" // optional - RxJava2 support for Room implementation "androidx.room:room-rxjava2:$room_version" // optional - RxJava3 support for Room implementation "androidx.room:room-rxjava3:$room_version" // optional - Guava support for Room, including Optional and ListenableFuture implementation "androidx.room:room-guava:$room_version" // optional - Test helpers testImplementation "androidx.room:room-testing:$room_version" // optional - Paging 3 Integration implementation "androidx.room:room-paging:$room_version" }
প্রাথমিক উপাদান
রুমে তিনটি প্রধান উপাদান রয়েছে:
- ডাটাবেস ক্লাস যা ডাটাবেস ধারণ করে এবং আপনার অ্যাপের সংরক্ষিত ডেটার সাথে অন্তর্নিহিত সংযোগের জন্য প্রধান অ্যাক্সেস পয়েন্ট হিসেবে কাজ করে।
- ডেটা এনটিটি যা আপনার অ্যাপের ডেটাবেসের টেবিলগুলোকে উপস্থাপন করে।
- ডেটা অ্যাক্সেস অবজেক্ট (DAO) হলো এমন মেথড যা ব্যবহার করে আপনার অ্যাপ ডাটাবেসে ডেটা কোয়েরি, আপডেট, ইনসার্ট এবং ডিলিট করতে পারে।
ডাটাবেস ক্লাসটি আপনার অ্যাপকে সেই ডাটাবেসের সাথে যুক্ত DAO-গুলোর ইনস্ট্যান্স সরবরাহ করে। এর ফলে, অ্যাপটি সংশ্লিষ্ট ডেটা এনটিটি অবজেক্টের ইনস্ট্যান্স হিসেবে ডাটাবেস থেকে ডেটা পুনরুদ্ধার করতে DAO-গুলো ব্যবহার করতে পারে। অ্যাপটি সংজ্ঞায়িত ডেটা এনটিটিগুলো ব্যবহার করে সংশ্লিষ্ট টেবিল থেকে সারি আপডেট করতে, অথবা সন্নিবেশের জন্য নতুন সারি তৈরি করতেও পারে। চিত্র ১-এ Room-এর বিভিন্ন উপাদানের মধ্যকার সম্পর্ক দেখানো হয়েছে।

নমুনা বাস্তবায়ন
এই বিভাগে একটিমাত্র ডেটা এনটিটি এবং একটিমাত্র ডিএও (DAO) সহ একটি রুম (Room) ডেটাবেসের বাস্তবায়নের উদাহরণ উপস্থাপন করা হয়েছে।
ডেটা সত্তা
নিম্নলিখিত কোডটি একটি User ডেটা এনটিটি সংজ্ঞায়িত করে। User এর প্রতিটি ইনস্ট্যান্স অ্যাপের ডাটাবেসের একটি user টেবিলের একটি সারিকে প্রতিনিধিত্ব করে।
কোটলিন
@Entity data class User( @PrimaryKey val uid: Int, @ColumnInfo(name = "first_name") val firstName: String?, @ColumnInfo(name = "last_name") val lastName: String? )
জাভা
@Entity public class User { @PrimaryKey public int uid; @ColumnInfo(name = "first_name") public String firstName; @ColumnInfo(name = "last_name") public String lastName; }
Room-এর ডেটা এনটিটি সম্পর্কে আরও জানতে, “Defining data using Room entities” দেখুন।
ডেটা অ্যাক্সেস অবজেক্ট (DAO)
নিম্নলিখিত কোডটি UserDao নামক একটি DAO সংজ্ঞায়িত করে। UserDao সেই মেথডগুলো সরবরাহ করে যা অ্যাপের বাকি অংশ user টেবিলের ডেটার সাথে ইন্টারঅ্যাক্ট করতে ব্যবহার করে।
কোটলিন
@Dao interface UserDao { @Query("SELECT * FROM user") fun getAll(): List<User> @Query("SELECT * FROM user WHERE uid IN (:userIds)") fun loadAllByIds(userIds: IntArray): List<User> @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") fun findByName(first: String, last: String): User @Insert fun insertAll(vararg users: User) @Delete fun delete(user: User) }
জাভা
@Dao public interface UserDao { @Query("SELECT * FROM user") List<User> getAll(); @Query("SELECT * FROM user WHERE uid IN (:userIds)") List<User> loadAllByIds(int[] userIds); @Query("SELECT * FROM user WHERE first_name LIKE :first AND " + "last_name LIKE :last LIMIT 1") User findByName(String first, String last); @Insert void insertAll(User... users); @Delete void delete(User user); }
DAO সম্পর্কে আরও জানতে, ‘Room DAO ব্যবহার করে ডেটা অ্যাক্সেস করা’ দেখুন।
ডাটাবেস
নিম্নলিখিত কোডটি ডাটাবেস ধারণ করার জন্য একটি AppDatabase ক্লাস সংজ্ঞায়িত করে। AppDatabase ডাটাবেসের কনফিগারেশন নির্ধারণ করে এবং সংরক্ষিত ডেটাতে অ্যাপের প্রধান অ্যাক্সেস পয়েন্ট হিসেবে কাজ করে। ডাটাবেস ক্লাসটিকে অবশ্যই নিম্নলিখিত শর্তগুলো পূরণ করতে হবে:
- ক্লাসটিকে অবশ্যই একটি
@Databaseঅ্যানোটেশন দিয়ে চিহ্নিত করতে হবে, যার মধ্যে একটিentitiesঅ্যারে থাকবে এবং এই অ্যারেতে ডাটাবেসের সাথে যুক্ত সমস্ত ডেটা এনটিটি তালিকাভুক্ত থাকবে। - ক্লাসটি অবশ্যই একটি অ্যাবস্ট্রাক্ট ক্লাস হতে হবে যা
RoomDatabaseএক্সটেন্ড করে। - ডাটাবেসের সাথে যুক্ত প্রতিটি DAO ক্লাসের জন্য, ডাটাবেস ক্লাসটিকে অবশ্যই একটি অ্যাবস্ট্রাক্ট মেথড সংজ্ঞায়িত করতে হবে, যেটির কোনো আর্গুমেন্ট থাকবে না এবং যা DAO ক্লাসের একটি ইনস্ট্যান্স রিটার্ন করবে।
কোটলিন
@Database(entities = [User::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun userDao(): UserDao }
জাভা
@Database(entities = {User.class}, version = 1) public abstract class AppDatabase extends RoomDatabase { public abstract UserDao userDao(); }
দ্রষ্টব্য: যদি আপনার অ্যাপ একটি একক প্রসেসে চলে, তাহলে একটি AppDatabase অবজেক্ট ইনস্ট্যানশিয়েট করার সময় আপনার সিঙ্গেলটন ডিজাইন প্যাটার্ন অনুসরণ করা উচিত। প্রতিটি RoomDatabase ইনস্ট্যান্স বেশ ব্যয়বহুল, এবং একটি একক প্রসেসের মধ্যে আপনার একাধিক ইনস্ট্যান্সে অ্যাক্সেসের প্রয়োজন খুব কমই হয়।
আপনার অ্যাপ যদি একাধিক প্রসেসে চলে, তাহলে আপনার ডাটাবেস বিল্ডার ইনভোকেশনে enableMultiInstanceInvalidation() অন্তর্ভুক্ত করুন। এর ফলে, যখন প্রতিটি প্রসেসে AppDatabase এর একটি করে ইনস্ট্যান্স থাকবে, তখন আপনি একটি প্রসেসে শেয়ার করা ডাটাবেস ফাইলটি ইনভ্যালিডেট করতে পারবেন এবং এই ইনভ্যালিডেশনটি স্বয়ংক্রিয়ভাবে অন্যান্য প্রসেসের AppDatabase ইনস্ট্যান্সগুলোতেও ছড়িয়ে পড়বে।
ব্যবহার
ডেটা এনটিটি, ডিএও এবং ডেটাবেস অবজেক্ট সংজ্ঞায়িত করার পরে, আপনি ডেটাবেসের একটি ইনস্ট্যান্স তৈরি করতে নিম্নলিখিত কোডটি ব্যবহার করতে পারেন:
কোটলিন
val db = Room.databaseBuilder( applicationContext, AppDatabase::class.java, "database-name" ).build()
জাভা
AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "database-name").build();
এরপর আপনি AppDatabase এর অ্যাবস্ট্রাক্ট মেথডগুলো ব্যবহার করে DAO-এর একটি ইনস্ট্যান্স পেতে পারেন। আবার, আপনি DAO ইনস্ট্যান্সের মেথডগুলো ব্যবহার করে ডাটাবেসের সাথে ইন্টারঅ্যাক্ট করতে পারেন:
কোটলিন
val userDao = db.userDao() val users: List<User> = userDao.getAll()
জাভা
UserDao userDao = db.userDao(); List<User> users = userDao.getAll();
অতিরিক্ত সম্পদ
Room সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত উৎসগুলো দেখুন:
