Room ব্যবহার করে লোকাল ডেটাবেসে ডেটা সেভ করা   Android Jetpack-এর অংশ।

Kotlin Multiplatform ব্যবহার করে দেখুন
Kotlin Multiplatform অন্যান্য প্ল্যাটফর্মের সাথে ডেটাবেস লেয়ার শেয়ার করার অনুমতি দেয়। KMP-তে কীভাবে Room Database সেট-আপ ও ব্যবহার করতে হয় তা জানুন

যেসব অ্যাপে প্রচুর পরিমাণে স্ট্রাকচার্ড ডেটা ম্যানেজ করা হয়, সেইসব অ্যাপে লোকালি ডেটা সেভ করে রাখলে অনেক সুবিধা পাওয়া যায়। সবচেয়ে সাধারণ ব্যবহারের ক্ষেত্রে প্রাসঙ্গিক ডেটা ক্যাশে করা হয় যাতে ডিভাইস নেটওয়ার্ক অ্যাক্সেস করতে না পারলেও, আপনার ব্যবহারকারীরা অফলাইনে থাকাকালীন সেই কন্টেন্ট ব্রাউজ করতে পারেন।

SQLite-এর সম্পূর্ণ ক্ষমতা ব্যবহার করার পাশাপাশি সাবলীলভাবে ডেটাবেস অ্যাক্সেস করার অনুমতি দিতে, Room পারসিসটেন্স লাইব্রেরি SQLite-এর উপরে একটি অ্যাবস্ট্রাকশন লেয়ার প্রদান করে। বিশেষ করে, Room নিম্নলিখিত সুবিধাগুলি প্রদান করে:

  • SQL কোয়েরির কম্পাইল-টাইম যাচাইকরণ।
  • সুবিধাজনক অ্যানোটেশন যা পুনরাবৃত্তিমূলক এবং ভুল-প্রবণ বয়লারপ্লেট কোড কম করে।
  • ডেটাবেস মাইগ্রেশনের সুবিন্যস্ত পাথ।

আমরা সরাসরি SQLite API ব্যবহার করার পরিবর্তে Room ব্যবহার করার সাজেশন দিই।

সেট-আপ করুন

আপনার অ্যাপে Room ব্যবহার করতে, আপনার মডিউলের build.gradle.kts ফাইলে নিম্নলিখিত ডিপেন্ডেন্সি যোগ করুন। অ্যানোটেশন প্রসেসিংয়ের জন্য Room 3.0-তে KSP প্রয়োজন।

কোটলিন

dependencies {
    val room_version = "3.0.3"

    implementation("androidx.room3:room3-runtime:$room_version")
    ksp("androidx.room3:room3-compiler:$room_version")
}

গ্রুভি

dependencies {
    def room_version = "3.0.3"

    implementation "androidx.room3:room3-runtime:$room_version"

    ksp "androidx.room3:room3-compiler:$room_version"
}

প্রাথমিক কম্পোনেন্ট

Room-এ তিনটি প্রধান কম্পোনেন্ট আছে:

  • ডেটাবেস ক্লাস যা ডেটাবেস হোল্ড করে এবং আপনার অ্যাপের সেভ করা ডেটার সাথে অন্তর্নিহিত কানেকশনের জন্য প্রধান অ্যাক্সেস পয়েন্ট হিসেবে কাজ করে।
  • ডেটা এন্টিটি যা আপনার অ্যাপের ডেটাবেসে টেবিলকে উপস্থাপন করে।
  • ডেটা অ্যাক্সেস অবজেক্ট (DAO) যা এমন ফাংশন প্রদান করে যা আপনার অ্যাপ ডেটাবেসে কোয়েরি, আপডেট, ইনসার্ট ও ডেটা মুছে ফেলার জন্য ব্যবহার করতে পারে।

Database ক্লাস আপনার অ্যাপকে সেই ডেটাবেসের সাথে যুক্ত DAO-এর ইনস্ট্যান্স প্রদান করে। এর পরিবর্তে, অ্যাপটি সংশ্লিষ্ট ডেটা এন্টিটি অবজেক্টের ইনস্ট্যান্স হিসেবে ডেটাবেস থেকে ডেটা রিট্রিভ করতে DAO ব্যবহার করতে পারে। এছাড়াও, অ্যাপটি সংশ্লিষ্ট টেবিল থেকে সারি আপডেট করতে অথবা ইনসার্ট করার জন্য নতুন সারি তৈরি করতে সংজ্ঞায়িত ডেটা এন্টিটি ব্যবহার করতে পারে। ১ নম্বর চিত্রে Room-এর বিভিন্ন কম্পোনেন্টের মধ্যে সম্পর্ক দেখানো হয়েছে।

ছবি ১. 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
)

Room-এ ডেটা এন্টিটি সম্পর্কে আরও জানতে, Room এন্টিটি ব্যবহার করে ডেটা সংজ্ঞায়িত করা দেখুন।

ডেটা অ্যাক্সেস অবজেক্ট (DAO)

নিচে দেওয়া কোড UserDao নামের একটি DAO-কে সংজ্ঞায়িত করে। UserDao এমন ফাংশন প্রদান করে যা অ্যাপের বাকি অংশ user টেবিলে ডেটার সাথে ইন্টার‍্যাক্ট করতে ব্যবহার করে।

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    suspend fun getAll(): List<User>

    @Query("SELECT * FROM user WHERE uid IN (:userIds)")
    suspend fun loadAllByIds(userIds: IntArray): List<User>

    @Query(
        """
        SELECT * FROM user
        WHERE first_name LIKE :first AND last_name LIKE :last LIMIT 1
        """
    )
    suspend fun findByName(first: String, last: String): User

    @Insert
    suspend fun insertAll(vararg users: User)

    @Delete
    suspend fun 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
}

মনে রাখবেন: আপনার অ্যাপ যদি একটি প্রসেসে চলে, তাহলে AppDatabase অবজেক্ট ইনস্ট্যানশিয়েট করার সময় আপনাকে সিঙ্গলটন ডিজাইন প্যাটার্ন ফলো করতে হবে। প্রতিটি RoomDatabase ইনস্ট্যান্স বেশ দামি এবং আপনাকে একটি প্রসেসের মধ্যে একাধিক ইনস্ট্যান্স অ্যাক্সেস করার প্রয়োজন খুব কমই হয়।

আপনার অ্যাপ একাধিক প্রসেসে রান করলে, আপনার enableMultiInstanceInvalidation() ডেটাবেস বিল্ডারে ইনভোকেশন যোগ করুন। এইভাবে, প্রতিটি প্রসেসে AppDatabase থাকলে, আপনি একটি প্রসেসে শেয়ার করা ডেটাবেস ফাইল বাতিল করতে পারবেন, এবং এই বাতিলকরণ অটোমেটিক অন্যান্য প্রসেসের মধ্যে থাকা AppDatabase-এর ইনস্ট্যান্সে প্রোপাগেট হয়ে যাবে।

ব্যবহার

ডেটা এন্টিটি, DAO ও ডেটাবেস অবজেক্ট ডিফাইন করার পরে, আপনি ডেটাবেসের ইনস্ট্যান্স তৈরি করতে নিম্নলিখিত কোড ব্যবহার করতে পারবেন:

val db =
    Room.databaseBuilder<AppDatabase>(applicationContext, "database-name")
        .setDriver(AndroidSQLiteDriver())
        .build()

তারপরে, DAO-এর একটি ইনস্ট্যান্স পেতে আপনি AppDatabase থেকে অ্যাবস্ট্রাক্ট ফাংশন ব্যবহার করতে পারবেন। এর পরিবর্তে, আপনি ডেটাবেসের সাথে ইন্টার‍্যাক্ট করতে DAO ইনস্ট্যান্স থেকে ফাংশন ব্যবহার করতে পারবেন:

val userDao = db.userDao()
val users: List<User> = userDao.getAll()

অতিরিক্ত রিসোর্স

Room সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত রিসোর্স দেখুন:

নমুনা