数据持久化技术:文件存储、SharedPreferences存储以及数据库存储

文件存储
这里实现了一个存储EditText中输入内容与恢复

package com.example.filepersistencetest

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.EditText
import android.widget.Toast
import java.io.*
import java.lang.StringBuilder

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val editText : EditText = findViewById(R.id.editText)

        val inputText = load()
        if (inputText.isNotEmpty()){
            editText.setText(inputText)
            editText.setSelection(inputText.length) //光标移动到末尾方便再次输入
            Toast.makeText(this,"Restoring successed",Toast.LENGTH_SHORT).show()
        }
    }

    override fun onDestroy() {
        super.onDestroy()

        val editText : EditText = findViewById(R.id.editText)
        val inputText = editText.text.toString()
        save(inputText)
    }

    /use是kotlin中内置扩展函数,可以保证在lambda表达式中代码全部执行完成后自动将外层的流关闭,
    / 这样就不需要写finally去手动关闭流

    /通过openFileOutput()得到FileOutputStream对象,再借助它构建出OutputStreamWriter对象,
    /接着在使用OutputStreamWriter构建出BufferedWriter对象,就可以用BufferedWriter将文本写入文件了。
    private fun save(inputText : String){
        try {
            val output = openFileOutput("data",Context.MODE_PRIVATE)
            val writer = BufferedWriter(OutputStreamWriter(output))
            writer.use {
            it.write(inputText)
        }
        }catch (e: IOException){
             e.printStackTrace()
        }
    }

    /先获取FileInputStream对象,然后借助它构建InputStreamReader对象,再使用其构造出BufferedReader对象,
    /这样就可以通过BufferedReader将文件中的数据一行行读取出来拼接到StringBuilder中,最后将读取内容返回

    /这里使用到了一个forEachLine函数,这也是kotlin内置扩展函数,可以将读到的每一行都回调到lambda表达式中,
    /我们在lambda表达式中完成拼接逻辑即可
    private fun load():String{
        val content = StringBuilder()
        try {
            val input = openFileInput("data")
            val reader = BufferedReader(InputStreamReader(input))
            reader.use {
                reader.forEachLine {
                    content.append(it)
                }
            }
        }catch (e:IOException){
            e.printStackTrace()
        }
        return content.toString()
    }
}

SharedPreferences存储

SharedPreferences存储(以键值对的方式)
 * 要使用SharedPreferences存储数据,首先要拿到SharedPreferences对象,有以下两种方式获取:
 * ①Context类中的getSharedPreferences()方法
 * 第一个参数用于指定SharedPreferences文件的名称,指定文件不存在则会创建
 * SharedPreferences文件都是放在/data/data/<package name>/shared_prefs/目录下的;
 * 第二个参数用于指定操作模式,目前只有MODE_PRIVATE可选,和传入0效果相同,表示当前应用才能对此SharedPreferences文件进行读写。
 * ②Activity类中的getPreferences()方法
 * 只接受一个操作模式参数,使用这个方法会自动将当前Activity的类名作为SharedPreferences文件名
 *
 * 得到SharedPreferences对象后就可以向其中存储数据了主要三步实现:
 * 一、调用SharedPreferences对象的edit()方法获取一个SharedPreferences.Editor对象
 * 二、向SharedPreferences.Editor对象中添加数据,比如添加布尔型用putBoolean()其他以此类推
 * 三、调用apply()方法将添加的数据提交,完成存储操作。

写入

saveButton.setOnClickListener { 
            val editor = getSharedPreferences("savedata",Context.MODE_PRIVATE).edit()
            editor.putBoolean("married",false)
            editor.putInt("age",22)
            editor.putString("name","Make")
            editor.apply()
        }

取出数据

restore.setOnClickListener { 
            val prefs = getSharedPreferences("savedata",Context.MODE_PRIVATE)
            val name = prefs.getString("name","")
            val age = prefs.getInt("age",0)
            val married = prefs.getBoolean("married",false)
            Log.d("MainActivity","$name is $age years old,and he married is $married")
        }

写入数据的时候用的是SharedPreferences.Editor对象,读取用的是SharedPreferences对象

SQLite数据库存储

Android为了让我们能够更加方便管理数据库,专门提供了一个SQLiteOpenHelper帮助类,借助它可以简单对数据库进行创建和升级
 *
 * SQLiteOpenHelper是一个抽象类,使用的话要自己创建类继承它,里面有两个抽象方法onCreate()onUpgrade()
 *
 * SQLiteOpenHelper还有两个重要的实例方法:
 * getReadableDatabase()getWritableDatabase()这两个方法都可以创建或打开一个现有的数据库(存在则打开,否则重新创建),
 * 并返回一个可对数据库进行读写操作的对象(可以借助此对象进行CURD操作),不同的是,
 * 当数据库不可写入时(例如磁盘满了)getReadableDatabase()会以只读方式打开,
 *getWritableDatabase()方法抛出异常
 *
 * SQLiteOpenHelper有两个构造方法可供重写,一般使用较少参数那个即可,此方法接收4个参数:
 * ①Context ②数据库名,创建数据库时使用就是这里指定的名称 ③允许我们在查询数据的时候返回一个自定义Cousor,一般传null
 * ④当前数据库的版本号
 * 构建出SQLiteOpenHelper实例再调用getReadableDatabase()getWritableDatabase()就能创建数据库了
 * 数据库文件存放在/data/data/<package name>/databases/目录下,重写的onCreate()方法也会得到执行,通常在此处理一些创建表的逻辑
 *
 * SQLite中的数据类型:integer表示整型,real表示浮点型,text表示文本类型,blob表示二进制类型
package com.example.databasetest

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.widget.Toast

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)"

    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,"Create successed",Toast.LENGTH_SHORT).show()
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        db!!.execSQL("drop table if exists Book")
        db!!.execSQL("drop table if exists Category")
        onCreate(db)
    }
}
package com.example.databasetest

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val createDatabase : Button = findViewById(R.id.createDatabase)
        val dbHelper = MyDatabaseHelper(this,"BookStore.db",2)

        createDatabase.setOnClickListener {
            dbHelper.writableDatabase
        }
    }
}

借助SQLiteDatabase对象进行CRUD操作
插入数据

addData.setOnClickListener { 
            val db = dbHelper.writableDatabase
            val values1 = ContentValues().apply { 
                //开始组装第一条数据
                put("name","The Da Vinci Code")
                put("author","Dan Brown")
                put("pages",54)
                put("price",16.96)
            }
            db.insert("Book",null,values1)
            //这里只对Book表其中四列数据进行了组装,因为id已经设为自动生成了,不再需要手动赋值
            val values2 = ContentValues().apply { 
                //开始组装第二条数据
                put("name","The Lost Symbol")
                put("author","Dan Brown")
                put("pages",510)
                put("price",14.95)
            }
            db.insert("Book",null,values2)
        }

更新数据

updateData.setOnClickListener { 
            val db = dbHelper.writableDatabase
            val values = ContentValues()
            values.put("price",10.99)
            db.update("Book",values,"name = ?", arrayOf("The Da Vinci Code"))
        }

删除数据

deleteData.setOnClickListener {
            val db = dbHelper.writableDatabase
            db.delete("Book","page > ?", arrayOf("500"))
        }

查询数据(最难的查)
在这里插入图片描述

queryData.setOnClickListener {
            val db = dbHelper.writableDatabase
            //查询Book表中的所有数据
            val cursor = db.query("Book",null,null,null,null,null,null)
            if (cursor.moveToFirst()){
                do {
                    //遍历cursor对象,取出数据并打印
                    val name = cursor.getString(cursor.getColumnIndex("name"))
                    val author = cursor.getString(cursor.getColumnIndex("author"))
                    val pages = cursor.getString(cursor.getColumnIndex("pages"))
                    val price = cursor.getString(cursor.getColumnIndex("price"))
                    Log.d("MainActivity","book name is $name")
                    Log.d("MainActivity","book author is $author")
                    Log.d("MainActivity","book pages is $pages")
                    Log.d("MainActivity","book price is $price")
                }while (cursor.moveToNext())
            }
            cursor.close()
        }

使用SQL操作数据库

        /添加数据
        db.execSQL("insert into Book (name,author,pages,price) values (?,?,?,?)"),
        arrayOf("The Da Vinci Code","Da Brown",454,16.96)
        /更新数据
        db.execSQL("update Book set price=?where name = ?", arrayOf("10.99","The Da Vinci Code"))
        /删除数据
        db.execSQL("delete from Book where pages > ?", arrayOf("500"))
        /查询数据
        val cursor = db.rawQuery("select * from Book",null)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值