温习Android基础知识——《第一行代码(第三版)》读书笔记 Chapter 7 数据持久化

第七章:数据存储全方案,详解持久化技术

目录

  • 第七章:数据存储全方案,详解持久化技术
    • 持久化技术简介
    • 文件存储
      • 简介
      • 用法
    • SharedPreferences存储
      • 简介
      • 用法
        • 使用SharedPreferences存储数据
        • 从SharedPreferences读取数据
    • SQLite数据库存储
      • 简介
      • 数据类型
      • 用法
        • 使用SQL操作数据库

持久化技术简介

瞬时数据即存储在内存中,有可能因为程序关闭或其它原因导致内存被回收而丢失的数据。
而数据持久化指的将那些内存中的瞬时数据保存到储存设备中,保证即使在手机或计算机关机的情况下,这些数据仍然不会丢失。
保存在内存中的数据就是出于瞬时状态的,保存在存储设备中的数据就是出于持久状态的。
而安卓为我们提供了三种方式用于简单的实现数据持久化功能。

文件存储

简介

文件存储是Android中最基本的数据存储方式,它不对数据进行任何格式化处理,所有的数据都是原封不动的保存到文件当中。因而它适合存储一些简单的文本数据或二进制数据。

用法

文件的操作模式有两种:MODE_PRIVATE表示当指定相同文件名的时候,所写入的内容将会覆盖原文件的内容,MODE_APPEND则往文件里追加内容,不存在就创建新文件。
写文件:

private fun save(inputText: String) {
    try {
        val output = openFileOutput("data", Context.MODE_PRIVATE)
        val writer = BufferedWriter(OutputStreamWriter(output))
        writer.use { it.write(inputText) }
         //use函数可以自动关闭外层流
    }catch (e : IOException){
        e.printStackTrace()
    }
}

读文件:

private fun load(fileName : String) : String{
    val content = StringBuilder()
    try {
        val input = openFileInput(fileName)
        val reader = BufferedReader(InputStreamReader(input))
        reader.use {
            reader.forEachLine { content.append(it) }
        }
    }catch (e : IOException){
        e.printStackTrace()
    }
    return content.toString()
}

SharedPreferences存储

简介

SharedPerferences是使用键值对的方式来存储数据的,支持多种不同的数据类型存储。

用法

使用SharedPreferences存储数据

要想使用SharedPreferences存储数据,首先要获取SharedPreferences对象,有两种方式:Context类中的getSharedPreferences()方法,与Activity类中的getPreferences()方法。
前者接收两个参数,SharedPreferences文件名和文件操作模式(目前只有一种MODE_PRIVATE可选,与传0效果相同),后者则只接收一个参数操作模式(因为使用这个方法的Activity的类名会被自动作为SharedPreferences的文件名)。
之后还有三步:
①调用SharedPreferences对象的edit方法获取一个SharedPreferences.Editor对象
②向SharedPreferences.Editor中添加数据
③调用apply方法将添加的数据提交,从而完成数据存储操作。

val editor = getSharedPreferences("data", 0).edit()
editor.putBoolean("married", false)
editor.putInt("age", 21)
editor.putString("name", "Jim")
editor.apply()

从SharedPreferences读取数据

与存储数据基本相同。

val prefs = getSharedPreferences("data",0)
val name = prefs.getString("name","unknown")
val age = prefs.getInt("age", 0)
val married = prefs.getBoolean("married",false)

SQLite数据库存储

简介

前两种数据持久化方式只适用于保存一些简单的数据和键值对,当需要存储大量复杂的关系型数据的时候,就需要数据库了。
SQLite是一款轻量级的关系型数据库,运算速度非常快,占用资源很少,既支持标准的SQL语法,也遵循数据库的ACID事务。简单易上手,甚至不需用户名密码就可以使用。

数据类型

类型 标识
整型 integer
浮点型 real
文本类型 text
二进制类型 blob

用法

Android为我们提供了SQLiteOpenHelper类对数据库进行创建和升级。
SQLiteOpenHelper类是一个抽象类,需要我们实现onCreate方法和 onUpgrade方法,这两种方法分别在数据库创建和升级的时候调用。
SQLiteOpenHelper类有两个构造方法,通常使用参数少一点的那个:

> SQLiteOpenHelper(Context, 数据库名, null, 数据库版本号)

获得SQLiteOpenHelper实例后,调用getReadablDatabase()方法或者getWritableDatabase()方法创建或打开一个现有的数据库。二者的差别在当数据库不可写入的时候(如磁盘空间已满),前者会返回一个只读的数据库,后者将出现异常。

val dbHelper = MyDatabaseHelper(this,"BookStore.db",3)
createDatabase.setOnClickListener {
    dbHelper.writableDatabase
}
class MyDatabaseHelper(val context: Context, name : String, version : Int) :
        SQLiteOpenHelper(context, name,null,version) {

    private val createBook = "create table Book (" +
            "id integer primary key autoincrement," +
            "author text," +
            "price real," +
            "pages integer," +
            "name text," +
            "category_id integer)"

    private val createCategory = "create table Category ("+
            "id integer primary key autoincrement,"+
            "category_name text,"+
            "category_code integer)"

    override fun onCreate(db: SQLiteDatabase) {
        db.execSQL(createBook)
        db.execSQL(createCategory)

        Toast.makeText(context, "数据库创建成功", Toast.LENGTH_SHORT).show()
    }
	//只要数据库版本号大于当前数据库版本号,就会执行升级函数
    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
    	//对每个版本都进行if判断,
    	//以确保APP在进行跨版本升级的时候每一次的数据库修改都能被全部执行
        if(oldVersion<=1){
            db.execSQL(createBook)
        }
        if (oldVersion<=2){
            db.execSQL("alter table Book add column category_id integer")
        }
        Toast.makeText(context, "数据库升级成功", Toast.LENGTH_SHORT).show()
    }

}
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val dbHelper = MyDatabaseHelper(this,"BookStore.db",3)
		//获得数据库
        createDatabase.setOnClickListener {
            dbHelper.writableDatabase
        }
		//增加数据
        addData.setOnClickListener {
            val db = dbHelper.writableDatabase
            val values1 = ContentValues().apply {
                put("name", "达芬奇密码")
                put("author","Dan Brown")
                put("pages",454)
                put("price",16.96)
            }
            val values2 = contentValuesOf (
                "name" to "第一行代码",
                "author" to "郭霖",
                "pages" to 692,
                "price" to 99.00
            )
            db.insert("Book",null, values1)
            db.insert("Book",null, values2)
        }
		//修改数据
        updateData.setOnClickListener {
            val db = dbHelper.writableDatabase
            val values1 = ContentValues().apply {
                put("price",10.99)
            }
            db.update("Book",values1,"name = ?", arrayOf("达芬奇密码"))
        }
		//
        deleteData.setOnClickListener {
            val db = dbHelper.writableDatabase
            db.delete("Book","pages>?", arrayOf("500"))
        }
		//查询数据
        queryData.setOnClickListener {
            val db = dbHelper.writableDatabase
            val cursor = db.query("Book", null,null,null,null,null,null)
            if (cursor.moveToFirst()){
                do {
                    val name = cursor.getString(cursor.getColumnIndex("name"))
                    val author = cursor.getString(cursor.getColumnIndex("author"))
                    val pages = cursor.getInt(cursor.getColumnIndex("pages"))
                    val price  = cursor.getDouble(cursor.getColumnIndex("price"))
                    Log.d("MainActivity","name is $name, author is $author, pages is $pages, price is $price")
                }while (cursor.moveToNext())
            }
            cursor.close()
        }
		//事务的原子性
        replaceData.setOnClickListener {
            val db = dbHelper.writableDatabase
            db.beginTransaction()
            try{
                db.delete("Book",null,null)
//                if (true){
//                    throw NullPointerException()
//                }
                val values = ContentValues().apply {
                    put("name", "第三行代码")
                    put("author","郭霖")
                    put("pages",692)
                    put("price",99.00)
                }
                db.insert("Book",null,values)
                db.setTransactionSuccessful()
            }catch (e : Exception){
                e.printStackTrace()
            }finally {
                db.endTransaction()
            }
        }
    }
}

使用SQL操作数据库

增删改都用的db.execSQL( )方法,查用的db.rawQuery()方法

你可能感兴趣的:(安卓基础知识)