Jetpack,liveDate,Room,Repository 初识

1 在项目的build 依赖

    def lifecycle_version = "2.2.0"
    def room_version = "2.3.0"
    implementation'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7'
    implementation'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.0'
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
    implementation("androidx.room:room-runtime:$room_version")
    annotationProcessor "androidx.room:room-compiler:$room_version"

注:如果项目是使用Kotlin语言来开发的,在添加room-compiler的时候使用kapt关键字,java语言开发的就使用annotationProcessor关键。否则会导致访问出错。

2.理解room的概念

  • Entity:实体类,对应的是数据库的一张表结构。需要使用注解 @Entity 标记。
  • Dao:包含访问一系列访问数据库的方法。需要使用注解 @Dao 标记。
  • Database:数据库持有者,作为与应用持久化相关数据的底层连接的主要接入点。需要使用注解 @Database 标记。 使用@Database注解需满足以下条件: 定义的类必须是一个继承于RoomDatabase的抽象类。 在注解中需要定义与数据库相关联的实体类列表。 包含一个没有参数的抽象方法并且返回一个带有注解的 @Dao。

3.创建bean


@Entity(tableName = "user_pro")
data class UserProEntity(

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "_id")
    val _id: Long,
    @ColumnInfo(name = "name")
    val name: String,
    @ColumnInfo(name = "age")
    val age: String,
    @ColumnInfo(name = "phone")
    val phone: String,
    @Ignore
    val isCode: Boolean

)

在@Entity注解中我们传入了一个参数 tableName用来指定表的名称。@PrimaryKey注解用来标注表的主键,并且使用autoGenerate = true 来指定了主键自增长。@ColumnInfo注解用来标注表对应的列的信息比如表名、默认值等等。@Ignore 注解顾名思义就是忽略这个字段,使用了这个注解的字段将不会在数据库中生成对应的列信息。也可以使用@Entity注解中的 ignoredColumns 参数来指定,效果是一样的。

4.对数据库进行操作

@Dao
interface UserProDao {

    @Query("SELECT * FROM user_pro")
    fun getAllUserPro(): LiveData<List<UserProEntity>>

    @Query("SELECT count(*) FROM user_pro")
    fun count(): Long

    @Query("Delete from user_pro")
    fun clear()

    @Query("SELECT * FROM user_pro WHERE name=:name")
    fun getUser(name: String): LiveData<UserProEntity>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(userProEntity: UserProEntity)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertAll(userProEntity: List<UserProEntity>)

    @Query("update user_pro set name=:name,age=:age where _id=:id")
    fun insertId(name: String, age: String, id: Long)

    @Query("delete from user_pro where _id=:id")
    fun deleteId(id: Long)

}

Dao类是一个 interface,其中定义了一系列的操作数据库的方法。通常我们操作数据库无非就是增删改查。Room也为我们的提供了相关的注解,有@Insert、@Delete、@Update 和 @Query。

@Query

我们先来看下 @Query 查询注解,它的参数时String类型,我们直接写SQL语句进行执行,而且编译的时候可以进行语法检查。比如我们根据ID查询某个用户的信息:

 @Query("SELECT * FROM user_pro")
 fun getAllUserPro(): LiveData<List<UserProEntity>>

@Insert

注解标注就可以:

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addUser(user: User)

我们看到直接中有个参数onConflict,表示的是当插入的数据已经存在时候的处理逻辑,有三种操作逻辑:REPLACE、ABORT和IGNORE。如果不指定则默认为ABORT终止插入数据。这里我们将其指定为REPLACE替换原有数据。

@Delete

如果需要删除表的数据则使用 @Delete注解:

@Delete
fun deleteUserByUser(user: User)

使用主键来查找要删除的实体。

@Update

如果需要修改某一条数据则使用 @Update注解,和@Delete一样也是根据主键来查找要删除的实体。

@Update
fun updateUserByUser(user: User)

上面说的 @Query 查询接受的参数是一个字符串,所以像删除或者更新我们也可以使用 @Query 注解来使用SQL语句来直接执行。比如根据userid来查询某个用户或者根据userid更新某个用户的姓名:

@Query("delete  from user where userId = :id ")
fun deleteUserById(id:Long)

@Query("update  user set userName = :updateName where userID =  :id")
fun update(id: Long, updateName: String)

 5.创建数据库并升级数据库

@Database(entities = [UserProEntity::class], version = 1, exportSchema = false)
abstract class TestDatabase : RoomDatabase() {

    abstract fun userProDao(): UserProDao

    companion object {
        private const val TAG = "TestDatabase"
        private var instance: TestDatabase? = null
        private val DATABASE_NAME: String = "my_db"
        fun getInstance(context: Context): TestDatabase {
            return instance ?: synchronized(this) {
                instance ?: buildDatabase(context).also { instance = it }
            }
        }


        private fun buildDatabase(context: Context): TestDatabase {
            return Room.databaseBuilder(context, TestDatabase::class.java, DATABASE_NAME)
                .addMigrations(MIGRATION_1_2)
                .addCallback(object : RoomDatabase.Callback() {
                    override fun onCreate(db: SupportSQLiteDatabase) {
                        super.onCreate(db)
                        Log.e(TAG, "onCreate: ")
                    }

                    override fun onOpen(db: SupportSQLiteDatabase) {
                        super.onOpen(db)
                        Log.e(TAG, "onOpen: ")
                    }
                })
                .build()
        }

        private val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(database: SupportSQLiteDatabase) {
                database.execSQL(
                    "CREATE TABLE IF NOT EXISTS USER_PRO" +
                            "('_id' LONG PRIMARY KEY AUTOINCREMENT NOT NULL," +
                            "'name' TEXT" +
                            "'age' TEXT" +
                            "'phone'TEXT" +
                            ")"
                )
            }

        }

    }

}

6.使用Repository思想

class UserProRepository {
    companion object {

        @Volatile
        private var instance: UserProRepository? = null

        fun getInstance() =
            instance ?: synchronized(this) {
                instance ?: UserProRepository().also { instance = it }
            }
    }

    private val userProDao: UserProDao =
        TestDatabase.getInstance(Utils.getApp().applicationContext).userProDao()


    suspend fun initUser() {
        val userProEntity: MutableList<UserProEntity> = ArrayList()
        var s_1 = UserProEntity(1, "小学", "11", "123456789",true)
        var s_2 = UserProEntity(2, "小学", "12", "123456789",true)
        var s_3 = UserProEntity(3, "中学", "13", "123456789",true)
        var s_6 = UserProEntity(6, "中学", "14", "123456789",true)
        var s_5 = UserProEntity(5, "大学", "19", "123456789",true)
        var s_4 = UserProEntity(4, "大学", "22", "123456789",true)
        userProEntity.add(s_1)
        userProEntity.add(s_2)
        userProEntity.add(s_3)
        userProEntity.add(s_6)
        userProEntity.add(s_5)
        userProEntity.add(s_4)
        val userProEntityList: MutableList<UserProEntity> = ArrayList()
        userProEntityList.clear()
        if (userProDao.count() != 0L) {
            userProEntityList.addAll(userProEntity)
        }
        userProDao.insertAll(userProEntityList)
    }

    //获取全部信息
    fun getUser() = userProDao.getAllUserPro()

    //保存某人信息
    fun saveUser(userProEntity: UserProEntity) = userProDao.insert(userProEntity)

    /**
     * 保存全部信息
     */
    suspend fun saveUserList(list: List<UserProEntity>) = userProDao.insertAll(list)

    /**
     * 删除全部
     */
    suspend fun deleteUser() = userProDao.clear()
    /**
     * 获取数量
     */
      fun getNumber()=userProDao.count()

}

7.结合VIewModel

class UserProfileViewModel(private val userProRepository: UserProRepository) : ViewModel() {

    private val myString: MutableLiveData<List<UserProEntity>> = MutableLiveData()

    lateinit var mutableList: LiveData<List<UserProEntity>>

    fun getUserPro(): MutableLiveData<List<UserProEntity>> {
        viewModelScope.launch {
            myString.postValue(userProRepository.getUser().value)
            //  mutableList=userProRepository.getUser()
        }
        return myString
    }


    fun initUser() {
        viewModelScope.launch {
            userProRepository.initUser()
        }
    }


    fun saveUserPro(userProEntity: UserProEntity) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                userProRepository.saveUser(userProEntity)
            }
        }
    }

    fun saveAllUser(list: List<UserProEntity>) {
        viewModelScope.launch {
            withContext(Dispatchers.IO) {
                userProRepository.saveUserList(list)
            }
        }
    }


    private fun loadNumberShowNumber() {
        usertNumber!!.value = userProRepository.getNumber()
    }

    private var usertNumber: MutableLiveData<Long>? = null

    fun getUserShowNumber(): LiveData<Long> {
        if (usertNumber == null) {
            usertNumber = MutableLiveData()
            loadNumberShowNumber()
        }
        return usertNumber!!
    }
}

8.设置模式

class SelfViewModelFactory(private var proRepository: UserProRepository): NewInstanceFactory() {

    @Suppress("UNCHECKED_CAST")
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        if (ViewModel::class.java.isAssignableFrom(modelClass)) {
            return try {
                modelClass.getConstructor(UserProRepository::class.java).newInstance(proRepository)
            } catch (e: NoSuchMethodException) {
                throw RuntimeException("Cannot create an instance of $modelClass", e)
            } catch (e: IllegalAccessException) {
                throw RuntimeException("Cannot create an instance of $modelClass", e)
            } catch (e: InstantiationException) {
                throw RuntimeException("Cannot create an instance of $modelClass", e)
            } catch (e: InvocationTargetException) {
                throw RuntimeException("Cannot create an instance of $modelClass", e)
            }
        }
        return super.create(modelClass)

    }
}

最后调用

class MainActivity : AppCompatActivity() {
    private  val TAG = "MainActivity"
    lateinit var viewModel: UserProfileViewModel
    lateinit var userProRepository: UserProRepository;
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewModel = ViewModelProvider(this, SelfViewModelFactory(userProRepository)).get(
            UserProfileViewModel::class.java
        )
        viewModel.initUser()

        viewModel.getUserPro().observe(this, Observer {
            Log.e(TAG, "onCreate: $it")
        })
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值