Kotlin课程学习一一数据存储(数据持久化)

目录

数据持久化

三种方式实现持久化

文件存储

SharedPrenrences存储

数据库存储

一、文件存储

存入数据:openFileOutput()

读取数据:openFileinput()

具体实现:

二、SharePreferences存储

获取对象:

添加数据:

数据存储:

具体实现:

三、数据库存储(SQLite)

添加数据:

更新数据:

删除数据:

查询数据:


数据持久化

数据持久化将瞬时数据保存到存储设备中,保证即使在手机或计算机关机状况下,这些数据仍然不会丢失。

三种方式实现持久化

文件存储

SharedPrenrences存储

介绍
使用键值对的方式存储数据。
当保存数据时提供一个对应的键,在读取数据的时候就可以通过这个键把对应的值取出来。

数据类型
支持多种不同数据类型存储,存储的数据为整型读取出来就是整型;存储的数据为字符串读取出来就是字符串。

数据库存储

一、文件存储

存入数据:openFileOutput()

Context类中的openFileOutput()方法,用于将数据存储到指定的文件中。默认存储到/data/data/<package name>/files/目录下。
如何进入该目录:
        调出搜索功能,输入:

Device File Explorer

        <package name>:

openFileOutput()有两个参数:

第一个参数是文件名

将数据存储到指定文件中,表示该文件已经存在,如果不存在则创建文件。

第二个参数是文件的操作模式

        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)
            }
        } catch (e:IOException){
            e.printStackTrace()
        }
    }

读取数据:openFileinput()

Context类中的openFileinput()方法,用于从文件中读取数据。

示例如下:

private fun load():String{
        val content=StringBuilder()
        try {
            val input = openFileInput("data")
            val reader = BufferedReader(InputStreamReader(input))
            reader.use {
                //forEachLine是kotlin的内置扩展,将读取的每个行内容添加到Lambda中
                reader.forEachLine {
                    //出现多个类时,带有继承关系指向父类的用this;如果不带有任何继承关系则使用it
                    content.append(it)
                }
            }
        }
        catch (e:IOException){
            e.printStackTrace()
        }
        return content.toString()
    }

具体实现:

代码

        MainActivity.kt

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.EditText
import android.widget.Toast
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.IOException
import java.io.InputStreamReader
import java.io.OutputStreamWriter

class MainActivity : AppCompatActivity() {
    lateinit var EditText1:EditText
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        EditText1=findViewById(R.id.editText)
        val inputText=load()
        if (inputText.isNotEmpty()){
            EditText1.setText(inputText)
            EditText1.setSelection(inputText.length)//获取文本长度,将光标移动到文本末尾
            Toast.makeText(this,"restore has success",Toast.LENGTH_LONG).show()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        val inputText=EditText1.text.toString()//调用其中的文本并转换成字符串
        save(inputText)
    }

    private fun save(inputText:String){
        //捕获错误
        try {
            val output=openFileOutput("data",Context.MODE_PRIVATE)
            //将数据存储到指定文件中,表示该文件已经存在,如果不存在则创建文件。第二个参数MODE_PRIVATE出现相同名则覆盖,即重新写入,MODE_APPEND在原文件后面接着写
            val writer=BufferedWriter(OutputStreamWriter(output))//BufferedWriter缓冲器,
            writer.use{
                it.write(inputText)
            }

        } catch (e:IOException){
            e.printStackTrace()
        }
    }
    //重新启动程序时EditText中能保留我们上次输入的内容
    private fun load():String{
        val content=StringBuilder()
        try {
            val input = openFileInput("data")
            val reader = BufferedReader(InputStreamReader(input))
            reader.use {
                //forEachLine是kotlin的内置扩展,将读取的每个行内容添加到Lambda中
                reader.forEachLine {
                    content.append(it)
                    //出现多个类,带有继承关系,指向父类的用this;如果不带有任何继承关系则使用it
                }
            }
        }
        catch (e:IOException){
            e.printStackTrace()
        }
        return content.toString()
    }
}

运行,在界面中的文本框输入内容。

结果:

Device File Explorer(在右侧栏最下方)中,进入data/data/当前项目名称文件夹,可以看到生成files/data文件,打卡查看,内容正是文本框输入内容。

二、SharePreferences存储

获取对象:

//调用SharePreferences对象的edit()方法获取一个SharePreferences.Editor对象
val editor=getSharedPreferences("data",Context.MOOE_PRIVATE).edit()

添加数据:

//添加一个布尔型数据就使用putBoolean()方法,添加字符串就使用putString()方法......
editor.putString("name","Tom")
editor.putInt("age",30)
editor.putBoolean("married",false)

数据存储:

//调用apply()方法将添加的数据提交
editor.apply()

具体实现:

建立两个按钮,点击按钮实现数据的存储和输出。

代码

        res/layout中activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="存入数据"
        />
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="显示数据"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

        MainActivity.kt

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.Toast

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val button1: Button = findViewById(R.id.button1)
        val button2: Button = findViewById(R.id.button2)
        //存入
        button1.setOnClickListener{
            val editor=getSharedPreferences("data", MODE_PRIVATE).edit()
            editor.putString("name","Tom")
            editor.putInt("age",30)
            editor.putBoolean("married",false)
            editor.apply()
        }
        //获取
        button2.setOnClickListener {
            val prefs=getSharedPreferences("data",Context.MODE_PRIVATE)
            //如果存入字段存在,则此处自动填入存入字段,如果存入字段不存在,则填入此处的值
            val name=prefs.getString("name","")
            val age=prefs.getInt("age",0)
            val married=prefs.getBoolean("married",true)
            val gradutate=prefs.getString("gradutate","he is postgraduate")
            //第一种形式:日志显示数据
            Log.d("MainActivity","name is $name")
            Log.d("MainActivity","age is $age")
            Log.d("MainActivity","married is $married")
            Log.d("MainActivity","gradutate is $gradutate")//未存入字段
        }
    }

}

运行,点击界面的存入数据按钮,再点击显示数据按钮,查看显示台

结果:

Device File Explorer(在右侧栏最下方)中,进入data/data/当前项目名称,可以看到生成了shared_pref/data.xml文件。

三、数据库存储(SQLite)

添加数据:

SQLite Database中提供了insert() 方法,

这个方法接收3个参数:第一个接受数据的表名,第二个是给未指定数据的字段赋NULL,一般不用设为null;第三个ContentValues()对象,传入的数据。

val dbHelper=MyDatabaseHelper(this,"BookStore.db",2)
val db=dbHelper.writableDatabase
val values=ContentValues().apply{
    put("author","Dan Brown")
    put("name","The Da Vinci Code")
    put("pages",280)
    put("price",13.28)
}
db.insert("Book",null,values)

更新数据:

SQLite Database中提供了update() 方法,
这个方法接收4个参数:第一个指定更新数据的表名; 第二个参数是Content Values对象, 要把更新数据在这里组装进去; 第三、第四个参数用于约束更新哪几行中的数据,不指定默认更新所有行

示例如下:

val dbHelper=MyDatabaseHelper(this,"BookStore.db",2)
val db=dbHelper.writableDatabase
val values=ContentValues()
values.put("price",10.99)
db.update("Book",values,"name=?",array Of("The Da Vinci Code"))

放进按钮进行监听:

import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.Toast

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val button: Button = findViewById(R.id.button1)
        //更新
        button.setOnClickListener{
            val dbHelper=MyDatabaseHelper(this,"BookStore.db",2)
            val db=dbHelper.writableDatabase
            val values=ContentValues()
            values.put("price",10.99)
            db.update("Book",values,"name=?",array Of("The Da Vinci Code"))
            Toast.makeText(this,"更新完成",Toast.LENGTH_SHORT).show()
        }
    }

}

删除数据:

SQLiteDatabase中提供了delete()方法,

这个方法接收3个参数:第一个指定需要删除的数据的表名;第二、第三个用于约束删除的是哪几行数据,不指定默认删除所有行

val dbHelper = MyDatabaseHelper(this,"BookStore.db",2)
val db = dbHelper.writableDatabase
db.delete("Book","pages>?",arrayOf("500"))

查询数据:

SQLiteDatabase中提供了query()方法,

这个方法需要传入7个参数:

query()参数 对应SQL部分 描述
table from table_name 指定查询的表名
columns select column1,column2 指定查询的列名
selection where column = value 指定where的约束条件
selectionArgs - 为where中的占位符提供具体的值
groupBy group by column 指定需要group by的列
having having column = value 对group by后的结果进一步约束
orderBy order by column1,column2 指定查询结果的排列方式
val dbHelper = MyDatabaseHelper(this, "BookStore.db", 2)
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.getInt(cursor.getColumnIndex("pages"))
        val price = cursor.getDouble(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()

猜你喜欢

转载自blog.csdn.net/m0_61059796/article/details/130203723
今日推荐