📅  最后修改于: 2023-12-03 14:43:41.237000             🧑  作者: Mango
Android中提供了一种操作SQLite数据库的方式,即使用Room Persistence Library。Room是Google官方推出的一种ORM(Object Relational Mapping)框架,实现了面向对象的SQLite操作方法。
相比于传统的基于SQL语句的数据库操作方式,Room提供了以下优势:
Room主要包括3个组件:Database、Entity和DAO。其中Entity作为数据库中数据表的实体类,DAO(Data Access Object)负责数据库操作,而Database作为整个数据库的抽象层。
Entity用于表示数据库中的表结构,用Kotlin中的data class进行定义,例如:
@Entity
data class User(
@PrimaryKey val uid: Int,
@ColumnInfo(name = "first_name") val firstName: String?,
@ColumnInfo(name = "last_name") val lastName: String?
)
其中,@PrimaryKey表示该字段为主键,@ColumnInfo表示该字段在表中对应的列名。
DAO定义了数据库的操作方法,通过@Dao注解进行标记,例如:
@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)
}
其中,@Query表示查询语句,@Insert表示插入语句,@Delete表示删除语句。
Database是整个Room的抽象层,提供了获取DAO实例的方法,例如:
@Database(entities = arrayOf(User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
其中,@Database用于指定实体类和数据库版本号。
dependencies {
def room_version = "2.3.0"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
}
@Entity
data class User(
@PrimaryKey val uid: Int,
@ColumnInfo(name = "first_name") val firstName: String?,
@ColumnInfo(name = "last_name") val lastName: String?
)
@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)
}
@Database(entities = arrayOf(User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
class MyApp :Application() {
val database : AppDatabase by lazy {
Room.databaseBuilder(this,AppDatabase::class.java,"database-name")
.allowMainThreadQueries() //如果主线程上操作数据库,则需要添加该方法
.build()
}
}
至此,就完成了一个基于Room实现的数据库操作。
使用Room实现本地化存储可以更加方便地实现应用的开发。可以使用Room提供的TypeConverter来表示自定义类型,在对象与数据库之间进行转换。
例如,需存储以下用户信息:
data class User(
val name: String,
val age: Int,
val address: Address
)
data class Address(
val street: String,
val city: String,
val zipcode: String
)
则可以分别定义两个TypeConverter:
class Converters {
@TypeConverter
fun fromAddress(address: Address): String {
val gson = Gson()
return gson.toJson(address)
}
@TypeConverter
fun toAddress(data: String): Address {
val typeOf = object : TypeToken<Address>() {}.type
return Gson().fromJson(data, typeOf)
}
}
在Database定义中添加TypeConverters注解进行标记:
@Database(entities = arrayOf(User::class), version = 1)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
接下来就可以使用用户信息进行数据库操作了。
总的来说,Room比较适合小型的应用程序,旨在为对象它是一个好的orm库。 对于那些需要更大而复杂的数据库,更大的存储数据和更多复杂查询的应用,则是SQLite的更好的选择。 虽然没有ORM适用于一切,但Room可以,能够在许多应用程序中以简单和高效的方式进行类和数据库之间的映射。 Room从Complexity角度为开发人员的日常工作提供了巨大的简化,并提高了应用程序的可维护性。 我个人非常喜欢这个库,我鼓励每个人尝试并看看它如何在您自己的应用程序中实现。