天天看点

【Android 练习】安卓存储练习

文章目录

  • ​​安卓存储练习​​
  • ​​一、概述​​
  • ​​二、SharedPreferennces 的使用​​
  • ​​1.activity_shared_prefences.xml布局​​
  • ​​2.SharedPreferencesActivity​​
  • ​​三、SQLite数据库​​
  • ​​1.SQLite简介​​
  • ​​2.SQLite的特点​​
  • ​​3.简单实现​​
  • ​​3.1 页面布局​​
  • ​​3.2 Activity功能实现​​
  • ​​3.3 效果展示​​

安卓存储练习

一、概述

存储方式:

  • SharedPreferences
  • 临时数据存储
  • 本质是xml,存在标签冗余
  • 不安全,xml可以直接解析
  • 数据轻量级
  • SQLite数据库
  • 增删改一般不使用缓存 — 实时
  • 数据量稍大,改动少 — 缓存应用场景
  • servlet 存储是文件形式,应用卸载后数据存储永久性消失
  • 内存
  • SD卡

​​返回顶部​​

二、SharedPreferennces 的使用

1.activity_shared_prefences.xml布局

【Android 练习】安卓存储练习
<?xml versinotallow="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".store.SharedPreferencesActivity">

    <EditText
        android:id="@+id/data1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="48dp"
        android:ems="10"
        android:hint="数据1" />

    <EditText
        android:id="@+id/data2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="0dp"
        android:layout_marginTop="114dp"
        android:ems="10"
        android:hint="数据2" />

    <Button
        android:id="@+id/sShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_marginTop="260dp"
        android:layout_marginEnd="53dp"
        android:text="系统获取"
        tools:layout_editor_absoluteX="89dp"
        tools:layout_editor_absoluteY="246dp" />

    <Button
        android:id="@+id/sAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_marginTop="205dp"
        android:layout_marginEnd="53dp"
        android:text="系统定义"
        tools:layout_editor_absoluteX="187dp"
        tools:layout_editor_absoluteY="334dp" />

    <Button
        android:id="@+id/pShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="41dp"
        android:layout_marginTop="258dp"
        android:text="自定义获取"
        tools:layout_editor_absoluteX="116dp"
        tools:layout_editor_absoluteY="427dp" />

    <Button
        android:id="@+id/pAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="41dp"
        android:layout_marginTop="202dp"
        android:text="自定义存入"
        tools:layout_editor_absoluteX="257dp"
        tools:layout_editor_absoluteY="446dp" />

    <Button
        android:id="@+id/pDelete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="41dp"
        android:layout_marginTop="320dp"
        android:text="自定义删除"
        tools:layout_editor_absoluteX="257dp"
        tools:layout_editor_absoluteY="446dp" />

    <Button
        android:id="@+id/pUpdate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="41dp"
        android:layout_marginTop="384dp"
        android:text="自定义修改"
        tools:layout_editor_absoluteX="257dp"
        tools:layout_editor_absoluteY="446dp" />
</RelativeLayout>      

​​返回顶部​​

2.SharedPreferencesActivity

package com.example.jyandroid.store;

import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.jyandroid.R;

public class SharedPreferencesActivity extends AppCompatActivity {

    EditText data1,data2;
    Button pAdd,pShow,pDelete,pUpdate,sAdd,sShow;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_shared_prefences);

        data1 = findViewById(R.id.data1);
        data2 = findViewById(R.id.data2);
        pAdd = findViewById(R.id.pAdd);
        pShow = findViewById(R.id.pShow);
        pDelete = findViewById(R.id.pDelete);
        pUpdate = findViewById(R.id.pUpdate);
        sAdd = findViewById(R.id.sAdd);
        sShow = findViewById(R.id.sShow);

        // 增
        pAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*构建 SharedPreferences
                   参数:名称+模式
                   1.MODE_PRIVATE           仅当前App中可使用共享数据
                   2.MODE_WORLD_READABLE    只读 ,已弃用
                   3.MODE_WORLD_WRITEABLE   可写 ,已弃用
                   4.MODE_APPEND            追加
                 */
                SharedPreferences sp = getApplicationContext().getSharedPreferences("myDatas", Context.MODE_PRIVATE);
                // 添加数据,首先要创建Editor
                SharedPreferences.Editor editor = sp.edit();
                editor.putString("data1Str",data1.getText().toString().trim());
                editor.putFloat("data2Float", Float.parseFloat(data2.getText().toString().trim()));
                // 一定要提交
                editor.commit();
                Toast.makeText(SharedPreferencesActivity.this,"存入成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 删
        pDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences sp = getApplicationContext().getSharedPreferences("myDatas", Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = sp.edit();
                editor.clear();
                // 一定要提交
                editor.commit();
                Toast.makeText(SharedPreferencesActivity.this,"删除成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 改
        pUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences sp = getApplicationContext().getSharedPreferences("myDatas", Context.MODE_PRIVATE);
                // 添加数据,首先要创建Editor
                SharedPreferences.Editor editor = sp.edit();
                editor.putString("data1Str",data1.getText().toString().trim());
                editor.putFloat("data2Float", Float.parseFloat(data2.getText().toString().trim()));
                // 一定要提交
                editor.commit();
                Toast.makeText(SharedPreferencesActivity.this,"修改成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 查
        pShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences sp = getApplicationContext().getSharedPreferences("myDatas", Context.MODE_PRIVATE);
                // 查询不需要使用Editor
                String data1Str = sp.getString("data1Str","");
                float data2Float = sp.getFloat("data2Float", 0.0f);
                String message = "数据1:" + data1Str +";数据2:"+ data2Float;
                Toast.makeText(SharedPreferencesActivity.this,message,Toast.LENGTH_SHORT).show();
            }
        });

        sAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*构建 SharedPreferences => PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                        使用系统默认的
                 */
                SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                // 添加数据,首先要创建Editor
                SharedPreferences.Editor editor = sp.edit();
                editor.putString("data1Str",data1.getText().toString().trim());
                editor.putFloat("data2Float", Float.parseFloat(data2.getText().toString().trim()));
                // 一定要提交
                editor.commit();
                Toast.makeText(SharedPreferencesActivity.this,"存入成功!",Toast.LENGTH_SHORT).show();
            }
        });
        sShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                // 查询不需要使用Editor
                String data1Str = sp.getString("data1Str","");
                float data2Float = sp.getFloat("data2Float", 0.0f);
                String message = "数据1:" + data1Str +";数据2:"+ data2Float;
                Toast.makeText(SharedPreferencesActivity.this,message,Toast.LENGTH_SHORT).show();
            }
        });

    }
}      

​​返回顶部​​

三、SQLite数据库

1.SQLite简介

SQLite是一款轻量级的开源的嵌入式数据库,由D.Richard Hipp在2000年发布。SQLite使用方便,性能出众,广泛应用于消费电子、医疗、工业控制、军事等各种领域。

​​返回顶部​​

2.SQLite的特点

(1)体积小:最低只需要几百K的内存就可以运行。

(2)性能高:对数据库的访问性能很高,其运行速度比Mysql等开源数据库要快很多。

(3)可移植性强:能支持各种32位和64位体系的硬件平台,也能在Windows、Linux、BSD、Mac OS、Solaries等软件平台中运行。

(4)SQL支持:SQLite支持ANSI SQL92中的大多数标准,提供了对子查询、视图、触发器等机制的支持。

(5)接口:SQLite为C、Java、PHP、Python等多种语言提供了API接口,所有的应用程序都必须通过接口访问SQLite数据库。

【Android 练习】安卓存储练习

1)编译器。编译器由词法分析、语法分析和中间代码生成三个模块组成。其中,词法分析模块和语法分析模块负责检查SQL语句的语法,然后把生成的语法树传递给中间代码生成模块。中间代码生成模块负责生成SQLite引擎可以识别的中间代码。

2)数据库引擎。数据库引擎是SQLite的核心,负责运行中间代码,指挥数据库的具体操作。

3)后台。后台由B树、页缓存和系统调用三个模块组成。其中,B树负责维护索引,页缓存负责页面数据的传送,系统调用负责和操作系统交互,最终实现数据库的访问。

值得一提的是,袖珍型的SQLite竟然可以支持高达2TB大小的数据库,每个数据库都是以单个文件的形式存在,这些数据都是以B-Tree的数据结构形式存储在磁盘上。

在事务处理方面,SQLite通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只有一个可以写入数据。在某个进程或线程想数据库执行写操作之前,必须获得独占锁。在获得独占锁之后,其他的读或写操作将不会再发生。

SQLite采用动态数据类型,当某个值插入到数据库时,SQLite将会检查它的类型,如果该类型与关联的列不匹配,SQLite则会尝试将该值转换成该列的类型,如果不能转换,则该值将作为本身的类型存储,SQLite称这为“弱类型”。但有一个特例,如果是INTEGER PRIMARY KEY,则其他类型不会被转换,会报一个“datatype missmatch”的错误。

概括来讲,SQLite支持 NULL、INTEGER、REAL、TEXT 和 BLOB 数据类型,分别代表空值、整型值、浮点值、字符串文本、二进制对象。

​​返回顶部​​

3.简单实现

3.1 页面布局

【Android 练习】安卓存储练习
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".store.SQLiteActivity">

    <EditText
        android:id="@+id/data"
        android:layout_width="399dp"
        android:layout_height="78dp"

        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_marginStart="9dp"
        android:layout_marginTop="447dp"
        android:layout_marginEnd="3dp" />

    <Button
        android:id="@+id/add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="62dp"
        android:layout_marginTop="178dp"
        android:text="增" />

    <Button
        android:id="@+id/delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_centerVertical="true"
        android:layout_marginStart="60dp"
        android:layout_marginTop="370dp"
        android:text="删" />

    <Button
        android:id="@+id/update"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="60dp"
        android:layout_marginTop="306dp"
        android:text="改" />

    <Button
        android:id="@+id/select"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="61dp"
        android:layout_marginTop="241dp"
        android:text="查" />

    <Button
        android:id="@+id/create_table"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="15dp"
        android:layout_marginTop="109dp"
        android:text="创建表" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="35dp"
        android:text="SQLite操作"
         />
</RelativeLayout>      

​​返回顶部​​

3.2 Activity功能实现

package com.example.jyandroid.store;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.jyandroid.R;
import java.io.File;
import java.util.ArrayList;

public class SQLiteActivity extends AppCompatActivity {

    // 按钮组件
    private EditText data;
    private Button create_table,add,delete,update,select;
    private SQLiteDatabase sqLiteDatabase;

    @RequiresApi(api = Build.VERSION_CODES.O_MR1)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_s_q_lite);

        // 获取组件
        data = findViewById(R.id.data);
        create_table = findViewById(R.id.create_table);
        add = findViewById(R.id.add);
        delete = findViewById(R.id.delete);
        update = findViewById(R.id.update);
        select = findViewById(R.id.select);

        // 创建数据库文件路径
        File path = new File("/data/data/com.example.jyandroid/databases/");
        // 判断文件路径是否存在
        if(!path.exists()){
            path.mkdirs();
        }
        // 创建数据库
        // openOrCreateDatabase
        // 不是openDatabase!!!
        sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(new File(path + "/myDB.db"),null);

        // 创建表
        create_table.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                   VARCHAR(n)  可变长度字符串, n <= 4000
                   CHAR(n)     固定长度字符类型
                   INTEGER     整型数据
                   REAL        浮点型数据
                   TEXT        文本字符串
                   BLOB        Blob(Binary long Object)是二进制长对象的意思,Blob通常用于存储大文件,典型的Blob内容是一张图片或者一个声音文件,由于他们的特殊性,必须使用特殊的方式来存储
                   DATE        日期类型
                   TIME        时间类型
                 */
                String sql =
                        "CREATE TABLE my_table1" +
                        "(" +
                        "id INTEGER PRIMARY KEY AUTOINCREMENT," +
                        "production_name TEXT," +
                        "production_price REAL" +
                        ")";
                sqLiteDatabase.execSQL(sql);
                // 提示
                Toast.makeText(SQLiteActivity.this,"创建表成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 增
        add.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                // 方式一:sql
                String sql = "insert into my_table (id,production_name,production_price) values ('苹果',12.22)";
                sqLiteDatabase.execSQL(sql);
                // 提示
                Toast.makeText(SQLiteActivity.this,"添加成功!",Toast.LENGTH_SHORT).show();
                */

                // 方式二:android 提供的内置方法 insert(表名,空值默认值,ContentValues对象)
                ContentValues datas = new ContentValues();
                // 插入第一条数据
                datas.put("production_name","苹果");
                datas.put("production_price","12.22");
                sqLiteDatabase.insert("my_table",null,datas);
                // 插入第二条数据
                datas.put("production_name","橙子");
                datas.put("production_price","18.50");
                sqLiteDatabase.insert("my_table",null,datas);
                // 插入第三条数据
                datas.put("production_name","橙子");
                datas.put("production_price","28.50");
                sqLiteDatabase.insert("my_table",null,datas);
                // 插入第四条数据
                datas.put("production_name","榴莲");
                datas.put("production_price","8.50");
                sqLiteDatabase.insert("my_table",null,datas);
                // 插入第五条数据
                datas.put("production_name","草莓");
                datas.put("production_price","15.22");
                sqLiteDatabase.insert("my_table",null,datas);
                // 提示
                Toast.makeText(SQLiteActivity.this,"添加成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 删
        delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                // 方式一:sql
                String sql = "delete from my_table  where id = 1";
                sqLiteDatabase.execSQL(sql);
                */

                // 方式二:android 提供的内置方法 delete(表名,where条件,where args[])
                String whereClause = "production_name=? and production_price=?" ;
                sqLiteDatabase.delete("my_table",whereClause,new String[]{"榴莲","8.50"});
                // 提示
                Toast.makeText(SQLiteActivity.this,"删除成功!",Toast.LENGTH_SHORT).show();
            }
        });

        // 改
        update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                // 方式一:sql
                String sql = "update my_table set production_name='芒果'";
                sqLiteDatabase.execSQL(sql);
                */

                // 方式二:Android提供的方法update(表名,ContentValues对象,whereClaus,where args[])
                ContentValues datas = new ContentValues();
                datas.put("production_price",15.00);
                String whereClause = "production_name=? and production_price>?";
                sqLiteDatabase.update("my_table",datas,whereClause,new String[]{"橙子","20.00"});
                // 提示
                Toast.makeText(SQLiteActivity.this,"修改成功!",Toast.LENGTH_SHORT).show();

            }
        });

        // 查
        select.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                // 方式一:sql
                String sql = "select * from my_table where production_name=? and production_price=?";
                Cursor cursor = sqLiteDatabase.rawQuery(sql,new String[]{"苹果","12.22"});
                while(cursor.moveToNext()){
                    Toast.makeText(SQLiteActivity.this,cursor.getColumnIndex(0),Toast.LENGTH_SHORT).show();
                }
                */

                /*
                  方法二: Android的方法query()
                    参数列表:
                        distinct:是否去重
                        table:表名。相当于select语句from关键字后面的部分。如果是多表联合查询,可以用逗号将两个表名分开。
                        columns:要查询出来的列名。相当于select语句select关键字后面的部分。
                        selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符“?”
                        selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常。
                        groupBy:相当于select语句group by关键字后面的部分
                        having:相当于select语句having关键字后面的部分
                        orderBy:相当于select语句order by关键字后面的部分,如:id desc, age asc;
                        limit:指定偏移量和获取的记录数,相当于select语句limit关键字后面的部分。
                 */
                String[] columns = {"id","production_name","production_price"};
                String whereClause = " production_price>?";
                Cursor cursor = sqLiteDatabase.query(true,"my_table",columns,whereClause,new String[]{"10.00"},
                        null,null,"id desc", String.valueOf(2));
                ArrayList<MyTable> arrayList = new ArrayList();
                // 遍历
                while (cursor.moveToNext()){
                    MyTable myTable = new MyTable();
                    myTable.setId(cursor.getInt(0));
                    myTable.setProduction_name(cursor.getString(1));
                    myTable.setProduction_price(cursor.getDouble(2));
                    arrayList.add(myTable);
                }
                // 直接显示查询的数据
                for(MyTable myTable:arrayList){
                    Toast.makeText(SQLiteActivity.this,myTable.toString(),Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}      

​​返回顶部​​

3.3 效果展示

创建表

【Android 练习】安卓存储练习

插入数据

【Android 练习】安卓存储练习
【Android 练习】安卓存储练习

删除数据

【Android 练习】安卓存储练习
【Android 练习】安卓存储练习

修改数据

【Android 练习】安卓存储练习
【Android 练习】安卓存储练习

查询数据

【Android 练习】安卓存储练习