文章目錄
- 安卓存儲練習
- 一、概述
- 二、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布局
<?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 效果展示
建立表
插入資料
删除資料
修改資料
查詢資料