栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android Room 数据库最佳入门教程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android Room 数据库最佳入门教程

引言
  • 本文章旨在记录学习Android JetPack库下的Room数据库的使用,不作过于深入原理的讲解,如有问题和建议请留言讨论。
1、Room 库概念及架构示意图 概念

Google的介绍:
  处理大量结构化数据的应用可极大地受益于在本地保留这些数据。最常见的使用场景是缓存相关的数据,这样一来,当设备无法访问网络时,用户仍然可以在离线状态下浏览该内容,
  Room 持久性库在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库
  Room 库具有一下优势:

  • 针对 SQL 查询的编译时验证
  • 可最大限度减少重复和容易出错的样板代码的方便注解
  • 简化了数据库迁移路径
架构示意图

主要组件

Room 包含三个主要组件

  • 数据库类(Room Database),用于保存数据库并作为应用持久性数据底层连接的主要访问点
  • 数据实体(Entities),用于表示应用的数据库中的表
  • 数据访问对象 (Data Access Objects【Dao】),提供您的应用可用于查询、更新、插入和删除数据库中的数据的方法
2、使用(Kotlin版【带注释】) 效果图展示

Android Room数据库操作

附上代码库地址:https://github.com/zqf-dev/ZRoomCode

依赖项添加
  • 在build.gradle(Project)文件下添加版本
ext {
    roomVersion = '2.4.2'
}
  • 在build.gradle(app)文件下添加
plugins {
	id 'com.android.application'
	id 'kotlin-android'
	// 添加kapt注解处理器
	id 'kotlin-kapt'
}

android {
	//排除原子函数模块并防止出现警告
	packagingOptions {
		exclude 'META-INF/atomicfu.kotlin_module'
	}
	kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies{
	//ktx
	implementation 'androidx.core:core-ktx:1.7.0'
	// room
	implementation "androidx.room:room-ktx:$rootProject.roomVersion"
	kapt "androidx.room:room-compiler:$rootProject.roomVersion"
	// 展示数据 adapter
    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.7'
}
实体类(Entities)创建

数据库(Database)创建

*注:exportSchema:是否允许数据库架构将导出到给定的文件夹中【 默认true 】

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

    //创建userDao
    abstract fun userDao(): UserDao
}
数据访问对象 (DAO)创建
@Dao
interface UserDao {
    // 查询
    @Query("SELECt * FROM loginUser")
    fun queryAllUser(): MutableList

    //根据姓名参数查询
    @Query("SELECt * FROM loginUser WHERe name = :name")
    fun queryFindUser(name: String): User?

    // 添加单条数据
    @Insert
    fun addUser(vararg user: User)

    // 添加批量数据
    @Insert(onConflict = OnConflictStrategy.REPLACe)
    fun addBatchUser(list: MutableList)

    // 更新某一个数据
    @Update
    fun updateUser(vararg user: User)

    //更新所有数据
    @Query("UPDATE loginUser set age='50'")
    fun updateAll()

    //删除某一个数据
    @Delete
    fun deleteSingle(vararg user: User)

    //删除表里所有数据
    @Query("DELETE FROM loginUser")
    fun deleteAllUser()
}
数据管理类封装
object DbManager {

    //数据库名
    private const val dbName: String = "zroom"

    //懒加载创建数据库
    val db: ZRoomDB by lazy {
        Room.databaseBuilder(
            App.app.applicationContext, ZRoomDB::class.java, dbName
        ).allowMainThreadQueries()//允许在主线程操作
            .addCallback(DbCreateCallBack)//增加回调监听
            .addMigrations()//增加数据库迁移
            .build()
    }

    private object DbCreateCallBack : RoomDatabase.Callback() {
        //第一次创建数据库时调用
        override fun onCreate(db: SupportSQLiteDatabase) {
            super.onCreate(db)
            Log.e("TAG", "first onCreate db version: " + db.version)
        }
    }
}
使用方法
class MainActivity : AppCompatActivity() {
    private val TagL = MainActivity::class.java.simpleName
    private lateinit var queryBtn: Button
    private lateinit var insertBtn: Button
    private lateinit var updateBtn: Button
    private lateinit var deleteBtn: Button
    private lateinit var resultRecycle: RecyclerView
    private var list = mutableListOf()
    var userDao: UserDao = DbManager.db.userDao()

    private val userAdapter by lazy {
        UserAdapter(R.layout.user_item_layout)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        findVbId()
    }

    private fun findVbId() {
        queryBtn = findViewById(R.id.query)
        insertBtn = findViewById(R.id.insert)
        updateBtn = findViewById(R.id.update)
        deleteBtn = findViewById(R.id.delete)
        resultRecycle = findViewById(R.id.result_recycle)
        resultRecycle.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
        resultRecycle.adapter = userAdapter
        userAdapter.addChildClickViewIds(R.id.item_delete, R.id.item_modify)
        queryBtn.setOnClickListener { query() }
        insertBtn.setOnClickListener { insertSingle() }
        deleteBtn.setOnClickListener { delete() }
        updateBtn.setOnClickListener { update() }
        userAdapter.setOnItemChildClickListener { _, view, position ->
            when (view.id) {
                R.id.item_delete -> singleDel(list[position])
                R.id.item_modify -> singleModify(list[position])
            }
        }
        insertAll()
    }

    
    private fun query() {
        list = userDao.queryAllUser()
        Log.e(TagL, list.toString())
        userAdapter.setList(list)
    }

    
    private fun insertAll() {
        runBlocking {
            if (userDao.queryAllUser().size == 0) {
                val mutableList: MutableList = mutableListOf()
                for (a in 1..3) {
                    val user = User("张三$a", 20 + a, "贵阳市观山湖区$a", "")
                    mutableList.add(user)
                }
                userDao.addBatchUser(mutableList)
                ToastUtil.show("批量新增数据成功")
            }
            query()
        }
    }

    
    private fun insertSingle() {
        val age = Random.nextInt(20, 40)
        val user = User("小二", age, "贵阳市观山湖区", "")
        userDao.addUser(user)
        ToastUtil.show("新增一条数据成功")
        query()
    }

    
    private fun delete() {
        userDao.deleteAllUser()
        ToastUtil.show("删除所有数据成功")
        query()
    }

    
    private fun update() {
        userDao.updateAll()
        ToastUtil.show("更新表里所有年龄数据成功")
        query()
    }

    
    private fun singleDel(singleUser: User) {
        userDao.deleteSingle(singleUser)
        ToastUtil.show("删除单条数据成功")
        query()
    }

    
    private fun singleModify(user: User) {
        user.aliasName = "修改的" + user.aliasName
        user.age = 100
        user.ads = "修改的地址白云区"
        userDao.updateUser(user)
        ToastUtil.show("更新单条数据成功")
        list.clear()
        query()
    }
}
数据库升级
  • Room 同时支持自动和手动方式进行增量迁移
  • *注:Room 在 2.4.0-alpha01 及更高版本中支持自动迁移。如果您的应用使用的是较低版本的 Room,则必须手动定义迁移。
1、手动迁移
  • 在实体类User里新增 字段gender
@Entity(tableName = "loginUser")
data class User(
    @PrimaryKey(autoGenerate = true)
    var id: Int = 0,
    @ColumnInfo(name = "name")
    var aliasName: String = "",
    var age: Int = 0,
    var ads: String = "",
    @Ignore
    var avatar: String = "",
    //数据库升级时测试的 新增字段
    var gender: Int = 0
) {
    constructor(aliasName: String, age: Int, ads: String, avatar: String) : this() {
        this.aliasName = aliasName
        this.age = age
        this.ads = ads
        this.avatar = avatar
    }
}
  • 1)创建 Migration 类,版本从v1—>v2,添加了‘gender’字段 默认值为1
  • 2)SQL语句:
      2.1)数据库表里增加字段
       ALTER TABLE loginUser ADD gender INTEGER Default 1 not null
      2.2)数据库新增表
       CREATE TABLE Car (id INTEGER, name TEXT, PRIMARY KEY(id))
    private object ZMigration : Migration(1, 2) {
        override fun migrate(database: SupportSQLiteDatabase) {
            Log.e(TagL, "执行数据库升级: ")
            //loginUser表中增加字段gender
            database.execSQL("ALTER TABLE loginUser ADD gender INTEGER Default 1 not null")
            //新建汽车数据表
            //database.exceSQL("CREATE TABLE Car (id INTEGER, name TEXT, PRIMARY KEY(id))")
        }
    }
//懒加载创建数据库
//懒加载创建数据库
    val db: ZRoomDB by lazy {
        Room.databaseBuilder(
            App.app.applicationContext, ZRoomDB::class.java, dbName
        ).allowMainThreadQueries()//允许在主线程操作
            .addCallback(DbCreateCallBack)//增加回调监听
            .addMigrations(ZMigration)//增加数据库迁移
            .build()
    }
  • 修改Database version版本为 2,依次调整
@Database(entities = [User::class], version = 2, exportSchema = false)
abstract class ZRoomDB : RoomDatabase() {

    //创建userDao
    abstract fun userDao(): UserDao
}

执行结果:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/878091.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号