文章目录
- 安卓存储
安卓存储
一、概述
存储方式:
- SharedPreferences
- 临时数据存储
- 本质是xml,存在标签冗余
- 不安全,xml可以直接解析
- 数据轻量级
- SQLite数据库
- 增删改一般不使用缓存 — 实时
- 数据量稍大,改动少 — 缓存应用场景
- servlet 存储是文件形式,应用卸载后数据存储永久性消失
- 内存
- SD卡
返回顶部
二、SharedPreferennces 的使用
1.activity_shared_prefences.xml布局
<?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数据库。
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 页面布局
<?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 效果展示
创建表
插入数据
删除数据
修改数据
查询数据
返回顶部