android开发数据持久化——使用数据库

准备知识:

  • 对关系型数据库有初步了解
  • 会写基本的SQL语句来管理数据库

一 什么是持久化:

  • 瞬时状态:数据存储在内存,可能会因为程序关闭或其他原因导致内存被回收而丢失数据
  • 持久状态:瞬时状态的数据已被保存到存储介质中,不随程序关闭而丢失

android提供了3种方式实现数据持久化:

  • SharedPerference
  • 文件存储
  • SQLite数据库

本文主要介绍使用SQLite数据库实现数据持久化

二 SQLite

2.1 简介:

  • 是一款轻量级关系型数据库,它的运行速度快,占用资源少。因而特别适合在移动设备上使用。
  • 不仅支持标准的SQL语法,而且遵循数据库事务管理

2.2 使用:

下面我们以用数据库记录APP的用户信息为例看看如何使用SQLiteOpenHelper:

Android 给出了帮助使用该数据库的类: SQLiteOpenHelper
我们创建一个类继承SQLiteOpenHelper来帮助使用数据库。

class MySQLiteHelper(context:Context) : SQLiteOpenHelper(context,DATABASE_NAME,null,DATABASE_VERSION) {

	//第一次创建该类时,调用的方法
    override fun onCreate(db:SQLiteDatabase) {
        db.execSQL(INIT_SENTENCE)
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        // 删除旧表
        db?.execSQL("DROP TABLE IF EXISTS User")

        // 创建新表(根据您的 INIT_SENTENCE)
        db?.execSQL(INIT_SENTENCE)

    }

    //传入用户类,在数据库中添加用户
    fun addUser(user: User) :Long{
        val values = ContentValues()
        values.put("account_num",user.getAccountNum())
        values.put("userName", user.getUserName())
        values.put("pwd", user.getPassword())
        values.put("age",user.getAge())
        values.put("email",user.getEmail())
        values.put("self_introduction",user.getSelfDescr())
        values.put("head_image",user.getHeadImage())

        val db = this.writableDatabase
        val success = db.insert("User", null, values)
        values.clear()
        db.close()
        return success
    }

    //根据账号查找用户,并返回User类型
    fun queryByAccount_num(account_num:String):User? {
        val query = "SELECT * FROM User WHERE account_num = ?"
        val db = this.readableDatabase
        val cursor = db.rawQuery(query, arrayOf(account_num))
        //注意判断查询结果是否为空不能使用 cursor==/!=null
        //可以使用moveToFirst()方法,当查询结果为空时该方法会返回false
        if (cursor.moveToFirst()) {
            val account_num_r = cursor.getString(cursor.getColumnIndexOrThrow("account_num"))
            val username_r = cursor.getString(cursor.getColumnIndexOrThrow("userName"))
            val pwd_r = cursor.getString(cursor.getColumnIndexOrThrow("pwd"))
            val age_r = cursor.getInt(cursor.getColumnIndexOrThrow("age"))
            val email_r = cursor.getString(cursor.getColumnIndexOrThrow("email"))
            val self_intro_r = cursor.getString(cursor.getColumnIndexOrThrow("self_introduction"))
            val head_image_r = cursor.getBlob(cursor.getColumnIndexOrThrow("head_image"))
            cursor.close()
            return User(account_num_r, username_r, pwd_r, age_r, email_r,self_intro_r,head_image_r)
        } else {
            return null
        }
    }

    //更新用户信息
    fun updateUserInfo(account_num: String,user_name:String,age:Int,email:String,self_description:String){
        println("user_name=$user_name,age = $age,email:$email,self_introduction:$self_description")
        val db = this.writableDatabase
        val values = ContentValues()
        values.put("userName",user_name)
        values.put("age",age)
        values.put("email",email)
        values.put("self_introduction",self_description)
        val whereClause = "account_num = ?"
        val whereArgs = arrayOf(account_num)

        db.update("User", values, whereClause, whereArgs)
        prtUsers()
        values.clear()
        db.close()
    }
    
    fun getNum():Int {
        val query = "SELECT COUNT(*) FROM User"
        val db = this.readableDatabase
        val cursor = db.rawQuery(query, null)
        var recordCount = 0

        if (cursor.moveToFirst()) {
            recordCount = cursor.getInt(0) // 获取第一列的值(记录数量)
        }

        cursor.close()
        db.close()
        return recordCount
    }

    fun clearUsers(){
        val db = this.writableDatabase
        db.delete("User", null, null) // 删除 User 表中的所有数据
        db.close()
    }

    companion object{
     	const val DATABASE_NAME = "Wandu.db" //数据库名称
        const val DATABASE_VERSION = 2  //数据库版本
        //初始化时的SQL语句
        const val INIT_SENTENCE =
            "CREATE TABLE User ("+
            "id INTEGER PRIMARY KEY AUTOINCREMENT,"+
            "account_num TEXT UNIQUE,"+
            "pwd TEXT NOT NULL,"+
           "userName TEXT NOT NULL,"+
            "age INTEGER DEFAULT 0," +
            "email TEXT," +
            "self_introduction TEXT," +
            "head_image BLOB" +
            ")";

    }

}

其中:

2.2.1. onCreat(db:SQLiteDatabase)方法:

如果数据库中没有任何内容会调用该方法,该方法完成新建数据库时的初始化行为:

db.execSQL(INIT_SENTENCE)
INIT_SENTENCE是一个SQL语句,创建一个名叫User的table,该表格具有id,account_num,pwd,userName,age,email等属性
ecexSQL(str)则是让数据库处理SQL语句str

2.2.2 onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int)方法:

数据库更新时会调用的方法

2.2.3.getReadableDatabase()和getWritableDatabase()方法:

返回一个SQLiteDatabase对象,借助这个对象就可以对数据进行增删改查操作

其中增删改使用**getWritableDatabase()方法得到可以写的数据库
查操作只需使用
getReadableDatabase()**方法得到可以读的数据库即可

2.3SQLiteDatabase类

2.3.1. 添加:insert()方法:

接收三个参数:

  • 第一个:表名,要操作的表
  • 第二个:null,在未指定添加数据的情况下给某些可为空的列自动赋值NULL
  • 第三个:要添加的数据,是一个ContentValues对象
    1. ContentValues使用put设置响应属性的值
      put()方法的第一个参数是属性名(也是table对应的列名),第二个参数是相应的属性值
    2. 在设置完属性值后,再调用insert方法将contentValue插入表格
    3. 如果要用同一个ContentValue实例连续insert两个数据,记得在第一次insert后将调用contentValue的insert方法

可参考addUser()方法中的代码:

//传入用户类,在数据库中添加用户
    fun addUser(user: User) :Long{
        val values = ContentValues()
        values.put("account_num",user.getAccountNum())
        values.put("userName", user.getUserName())
        values.put("pwd", user.getPassword())
        values.put("age",user.getAge())
        values.put("email",user.getEmail())
        values.put("self_introduction",user.getSelfDescr())
        values.put("head_image",user.getHeadImage())

        val db = this.writableDatabase
        val success = db.insert("User", null, values)
        values.clear()
        db.close()
        return success
    }

2.3.2. 查询:

rawQuery()方法
返回一个Cursor对象,查询到的所有数据从这个对象中取出

  • 第一个参数:一个sql语句
  • 第二个参数:一个list,用于“代替”sql中的 ‘?’.
	val query = "SELECT * FROM User WHERE account_num = ?"
    val db = this.readableDatabase
    val cursor = db.rawQuery(query, arrayOf(account_num))

这里的Where部分的意思是:
当表格中数据的account_num属性值为arrayOf(account_num)中的某一个时

给段实例代码:这段代码实现了根据account_num(账号)去数据库中查询取出数据,并由这些数据新建一个User类并返回

 //根据账号查找用户,并返回User类型
   //根据账号查找用户,并返回User类型
    fun queryByAccount_num(account_num:String):User? {
        val query = "SELECT * FROM User WHERE account_num = ?"
        val db = this.readableDatabase
        val cursor = db.rawQuery(query, arrayOf(account_num))
        //注意判断查询结果是否为空不能使用 cursor==/!=null
        //可以使用moveToFirst()方法,当查询结果为空时该方法会返回false
        if (cursor.moveToFirst()) {
            val account_num_r = cursor.getString(cursor.getColumnIndexOrThrow("account_num"))
            val username_r = cursor.getString(cursor.getColumnIndexOrThrow("userName"))
            val pwd_r = cursor.getString(cursor.getColumnIndexOrThrow("pwd"))
            val age_r = cursor.getInt(cursor.getColumnIndexOrThrow("age"))
            val email_r = cursor.getString(cursor.getColumnIndexOrThrow("email"))
            val self_intro_r = cursor.getString(cursor.getColumnIndexOrThrow("self_introduction"))
            val head_image_r = cursor.getBlob(cursor.getColumnIndexOrThrow("head_image"))
            cursor.close()
            return User(account_num_r, username_r, pwd_r, age_r, email_r,self_intro_r,head_image_r)
        } else {
            return null
        }
    }
  1. 对于查询结果是否为空的判断,不能判断cursor是否为null,直接使用cursor的moveToFirst();在方法在移到cursor的最前面的同时,返回boolean类型,当查询结果为空,会返回false
  2. 从cursor中获得查询结果:
    会使用形如cursor.getType(cursor.getColumnIndexOrThrow(column_name))的调用:
  • column_name:是要取的属性值在表中的属性名
  • getType()实则是根据要取出的属性类型选择方法:例如要取出的类型是String就是getString()方法

2.3.3. 更新:update()方法:

四个参数:

  • table:要更新的表名
  • value:要更新的数据
  • whereClause:要更新哪行的数据
  • whereArgs:上一个参数中占位符的值
  • 与insert方法一样,value的类型是ContentValue;在updata前首先准备好value,可以使用put方法,对于updata方法使用的ContentValue,只需要put要更新的属性名和属性值即可
  • 第三四个参数用于完成删选条件,

在这里插入图片描述

2.3.4. 删除:delete()方法:

三个参数:

  • table:要更新的表名
  • whereClause:约束要删除哪行的数据
  • whereArgs:上一个参数中占位符的值

参考clearUsers()方法:
这里的delete()方法第2、3个参数,均为null,说明没有限制,即删除所有User表格中数据

fun clearUsers(){
        val db = this.writableDatabase
        db.delete("User", null, null) // 删除 User 表中的所有数据
        db.close()
    }
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值