17讀書筆記之SQLite數據庫存儲
SQLite數據庫存儲
創建數據庫
Android管理數據庫提供了一個SQLiteOpenHelper幫助類。
借助這個類就可以簡單地對數據庫進行創建和升級。下面學習SQLiteOpenHelper的基本用法。
首先SQLiteOpenHelper是一個抽象類,我們要是用的話,需要創建一個自己的幫助類去繼承它。SQLiteOpenHelper中有兩個抽象方法。
onCreate()和onUpgrade()
我們必須在自己的幫助類里面重寫這兩個方法,然后分別在這兩個方法中去實現創建,升級數據庫的邏輯。
SQLiteOpenHelper中有兩個實例方法,
getReadableDatabase()和getWritableDatabase()。
這兩個方法都可以創建或打開一個現有的數據庫(如果數據庫已存在則直接打開,否則創建一個新的數據庫),并返回一個可對數據庫進行讀寫操作的對象。
不同的是,當數據庫不可寫入的時候(如磁盤空間已滿),getReadableDatabase()方法返回的對象將以只讀的方式去打開數據庫,
而getWritableDatabase()方法則將出現異常。
SQLiteOpenHelper中有兩個構造方法可供重寫,一般使用參數少一點的那個構造方法即可。
這個構造方法中接收4個參數:
第一個參數是Context,必須有它才能對數據庫操作。
第二個參數是數據庫名,創建數據庫時使用的就是這里指定的名稱。
第三個參數運行徐我們在查詢數據的時候返回一個自定義的Cursor,一般都傳入null。
第四個參數表示當前數據庫的版本號,可用于對數據庫進行升級操作。
構建出SQLiteOpenHelper的實例之后,再調用它的getReadableDatabase()或getWritableDatabase()方法就能夠創建數據庫了。
數據庫文件會存放在/data/data//databases/目錄下。
此時,重寫的onCreate()方法也會得到執行。所以通常會在這里去處理一些創建表的邏輯。
下面舉一個例子:創建一個DatabaseTest項目
我們創建一個名為BookStore.db的數據庫,然后再這個數據庫中新建一張Book表。表中有id(主鍵)、作者、價格、頁數、和書名等。
(在這里需要學者學習一下數據庫,本人學過兩個數據庫一個是mysql和oracle。如果沒學的話建議可以學一下mysql就可以)
Book表的創建表語句如下:
Create table Book(
id integer primary key autoincrement,
author text,
price real,
pages integer,
name text)
SQLite不想其他的數據庫擁有眾多復雜的數據類型,它的數據類型很簡單。
integer表示整形
real表示浮點型
text表示文本類型
blob表示二進制類型。
primary key將id列設為主鍵。
autoincrement關鍵字表示id列是自增長的。
新建MyDatabaseHelper類繼承自SQLiteOpenHelper
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK = "Create table Book("
+"id integer primary key autoincrement,"
+"author text,"
+"price real,"
+"pages integer,"
+"name text)";
private Context mContext;//?
public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
可以看到,把建表語句定義成了一個字符串常量,然后早onCreate方法中調用了SQLiteDatabase的execSQL()方法去執行這條建表語句。
修改activity_main.xml中的代碼:
<LinearLayout 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="net.nyist.lenovo.databasetest.MainActivity"
android:orientation="vertical">
<Button
android:id="@+id/craete_database"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create database"
/>
</LinearLayout>
布局文件很簡單,加入一個按鈕,用于創建數據庫。
最后修改MainActivity中的代碼:
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1);
Button createDatabase = (Button) findViewById(R.id.craete_database);
createDatabase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dbHelper.getWritableDatabase();
}
});
}
}
這里我們在onCreate()方法中構建了一個MyDatabaseHelper對象,并且通過構造函數的參數將數據庫名指定為BookStore.db,版本號指定為1,然后再Create database按鈕的點擊事件里調用getWritableDatabase()方法。遮陽擋點擊Create database按鈕時,就會檢測到當前程序中沒有BookStore.db這個數據庫,與實惠創建該數據庫并調用MyDatabaseHelper中的onCrewate()方法,這樣Book表也就創建了,并彈出提示創建成功。
下面運行程序:
那么怎么證明它們的確創建成功了呢?
adb是Android SDK中自帶的一個調試工具,使用這個工具可以直接對連接在電腦上的手機或模擬器進行調試操作,他存放在sdk的platform-tools目錄下,如果想要在命令行中使用這個工具,就需要先把它的路徑配置到環境變量里。
配置環境變量在這里就不多說了,不會的可以百度。
配置好之后,就可以使用adb工具了。打開命令提示符,輸入adb shell,就會進入到設備的控制臺。使用cd命令進入到/data/data/net.nyist.lenovo.databasetest/databases/目錄下,(在這里我的包名是net.nyist.lenovo.databasetes),并使用ls命令查看到該目錄里面的文件。
這時候目錄下出現了兩個數據庫文件:
一個正是我們創建的BookStore.db
而另一個BookStore.db-journal:則是為了讓數據庫能夠支持事務而產生的臨時文件。
接下來我們就要借助sqlite命令打開數據庫:
1.輸入sqlite3,后面加上數據庫名即可。(我剛開始一直出錯是沒有加數據庫名)。
2.這是就打開BookStore.db數據庫,現在就可以對這個數據庫中的表進行管理。
3.輸入.table,可以看到數據庫中有兩張表。android_metadata表是每個數據庫中都會自動生成的,不用管它。而另一張Book表就是我們在MyDatabaseHelper中創建的。
4.還可以通過.schema命令來查看它們的建表語句。
由此證明BookStore數據庫和Book表確實已經創建成功。之后輸入.exit或.quit命令可以退出數據庫的編輯,再輸入exit命令就可以退出設備控制臺。
升級數據庫
onUpgrade()方法適用于對數據庫進行升級的,它在真個數據庫的管理工作當中起著非常重要的作用。
目前DatabaseTest項目中已經有一張Book表用于存放書的各種詳細數據,添加一張Categroy表用于記錄圖書的分類。
比如Category表中有id(主鍵)、分類名和分類代碼這幾個列,那么建表語句就可以寫成:
create table Category(
id integer primary key autoincrement,
category_name text,
category_code integer)
接下來我們將這條建表語句添加到MyDatabaseHelper中,代碼如下所示:
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_CATEGORY = "create table Category("
+"id integer primary key autoincrement,"
+"category_name text,"
+"category_code integer)";
public static final String CREATE_BOOK = "Create table Book("
+"id integer primary key autoincrement,"
+"author text,"
+"price real,"
+"pages integer,"
+"name text)";
private Context mContext;//?
public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATEGORY);
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
onCreate(db);
}
}
可以看到,我們在onUpgrade()方法中執行了兩條drop語句,如果發現數據庫中已經存在Book表或Category表,就將這兩張表刪除掉,然后再調用onCreate()方法重新創建。這里先將已經存在的表刪除掉,因為如果在創建表時發現這張表已經存在了,就會直接報錯。
為了讓onUpgrade()方法執行,我們可以在SQLiteOpenHelper的構造方法里修改第四個參數,之前傳入的是1,現在只要傳比1大的數就可以讓onUpgrade()方法得到執行。
dbHelper = new MyDatabaseHelper(this,”BookStore.db”,null,2);
添加數據
對數據進行的操作無非就4種:CRUD
1.C:添加(Create)
**2.R:查詢(Retrieve)**
**3.U:更新(Update)**
**4.D:刪除(Delete)**
前面我們已經知道,調用SQLiteOpenHelper的getReadableDatabase()或getWritableDatabase()方法是可以用于創建和升級數據庫的,不僅如此,這兩個方法還會返回一個SQLiteDatabase()對象,借助這個對象就可以對數據進行CRUD操作了。
insert():添加數據。接收三個參數
第一個參數:表名,希望向那張表里添加數據,這里就傳入該表的名字。
第二個參數:在未指定添加數據的情況下給某些可為空的列自動復制NULL,一般不用這個功能,直接傳入null即可。
第三個參數:是一個ContentValues對象,它提供了一系列的put()方法重載,用于向ContentValues中添加數據,只需要將表中的每個列名以及相應的待添加數據傳入即可。
下面看例子:
修改activity_main.xml中的代碼:
只添加一個按鈕。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
······
<Button
android:id="@+id/add_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add data"
/>
</LinearLayout>
接著修改MainActivity的代碼:
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);
Button createDatabase = (Button) findViewById(R.id.craete_database);
createDatabase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dbHelper.getWritableDatabase();
}
});
Button addData = (Button) findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//先獲取到SQLiteDatabase對象
SQLiteDatabase db = dbHelper.getWritableDatabase();
//使用ContentValues來對要添加的數據進行組裝。
ContentValues values = new ContentValues();
//開始組裝第一條數據
values.put("name","The Da Vinci Code");
values.put("author","Dan Brown");
values.put("pages",454);
values.put("price",16.96);
db.insert("Book",null,values);//插入第一條數據
values.clear();
//開始組裝第二條數據
values.put("name","The Lost Symbol");
values.put("author","Dan Brown");
values.put("pages",510);
values.put("price",19.95);
db.insert("Book",null,values);//插入第二條數據
}
});
//調用了兩次insert()
}
}
點擊一下Adddata按鈕,此時兩條數據應該都已經添加成功。我們可以證實一下:
更新數據
SQLiteDatabase中也提供一個非常好用的update()方法。用于對數據進行更新 ,這個方法接收4個參數。
第一個參數:表名。
第二個參數:ContentValues對象。
第三個第四個參數用于約束更新某一行或某幾行中的數據,不指定的話默認就是更新所有行。
繼續修改activity_main.xml代碼:
添加一個更新按鈕:
<Button
android:id="@+id/update_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Update data"
/>
修改MainActivity中的代碼:
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);
Button createDatabase = (Button) findViewById(R.id.craete_database);
createDatabase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dbHelper.getWritableDatabase();
}
});
Button addData = (Button) findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
//開始組裝第一條數據
values.put("name","The Da Vinci Code");
values.put("author","Dan Brown");
values.put("pages",454);
values.put("price",16.96);
db.insert("Book",null,values);//插入第一條數據
values.clear();
//開始組裝第二條數據
values.put("name","The Lost Symbol");
values.put("author","Dan Brown");
values.put("pages",510);
values.put("price",19.95);
db.insert("Book",null,values);//插入第二條數據
}
});
Button updatadata = (Button) findViewById(R.id.update_data);
updatadata.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
//構造一個ContentValues對象,并且只它指定了一組數據。
ContentValues values = new ContentValues();
values.put("price",10.99);
db.update("Book",values,"name = ?",new String[]{ "The Da Vinci Code"});
//這里使用了第三第四個參數來指定具體更新哪幾行。
//第三個參數對應的是SQLwhere部分,表示更新所有name等于?的行,而?
//是一個占位符,可以通過第四個參數提供的一個字符串數組為第三個
//數中的每個占位符指定相應的內容。
//因此上述代碼想表達的意圖是將名字是The Da Vinci Code的這本書
//的價格改成10.99
}
});
}
}
運行如下:
刪除數據
SQLiteDatabase中提供了一個delete()方法,專門用于產出數據,這個方法接收3個參數。
第一個參數:表名。
第二個參數第三個參數又是用于約束刪除某一行或某幾行的數據,不指定的話就是默認刪除所有行。
修改activity_main.xml
添加刪除按鈕
<Button
android:id="@+id/delete_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Delete data"
/>
修改MainActivity
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);
·······
Button deletedata = (Button) findViewById(R.id.delete_data);
deletedata.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("Book","page > ?",new String[] {"500"});
}
});
}
}
我們在刪除按鈕的點擊事件里之名刪除Book表中的數據,并且通過第二,第三個參數來指定僅刪除頁數超過500頁的書。
運行程序:
查詢數據
我們都知道Structured Query Language,翻譯成中文就是結構化查詢語言。
它的大部分功能都體現在”查”這個字上,而”增刪改”只是其中的一小部分功能。
SQLiteDatabase中還提供了一個query()方法用于對數據進行查詢。這個方法的參數非常復雜,最短的一個方法重載也需要傳入7個參數。
第一個參數:表名。
第二個參數:用于指定去查詢那幾列,如果不指定則默認查詢所有列。
第三個第四個參數:用于約束查詢某一行或幾行的數據,不指定則默認查詢所有行的數據。
第五個參數:用于指定需要去group by的列,不指定則表示不對查詢結果進行group by操作。
第六個參數:用于對group by之后的數據進行進一步的過濾,不指定則表示不進行過濾。
第七個參數:用于指定查詢結果的排序方式,不指定則表示使用默認的排序方式。
修改:
activity_main.xml代碼:
<Button
android:id="@+id/query_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Query Data"
/>
修改MainActivity代碼:
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);
Button queryButton = (Button) findViewById(R.id.query_data);
queryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
//查詢Book中所有的數據
Cursor cursor = db.query("Book",null,null,null,null,null,null,null);
if (cursor.moveToFirst()){
do {
//遍歷Cursor對象,取出數據并打印
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
double 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();
}
});
}
}
運行如下:
智能推薦
Android數據存儲_SQLite數據庫存儲
Android數據存儲的方式有種,主要有三種。分別為:文件存儲,SharedPreference存儲,以及數據庫存儲。 這篇主要講SQLite數據庫存儲。 1.基本描述 Android自帶了一種輕量級數據庫SQLite。SQLite是一款輕量級的關系型數據庫,他的運算速度非常快,占用資源很少,通常只需要占用幾百K的資源就足夠了,因而特別適合在...
第一行代碼之SQLite數據庫存儲
SQLite數據庫存儲 6.3.1 創建數據庫 Android專門提供了一個 SQLiteOpenHelper幫助類對數據庫進行創建和升級 SQLiteOpenHelper需要創建一個自己的幫助類去繼承它并且重寫它的兩個抽象方法,即 onCreate() 和 onUpgrade() SQLiteOpenHelper 中有兩個重要的實例方法:getReadableDatabase() 和 getWr...
QML使用Sqlite數據庫存儲ListModel數據
(本文為utf-8格式,可以直接使用相應代碼) Models 是用來提供數據的,它既可以以 QML 的形式出現也可以是 C++的類。QML中的Model有ListModel、XmlListModel、 VisualItemModel;C++ 中的 Model 有 QAbstractItemModel、QStringList、 QList<QObject*>等。...
Android中的SQLite數據庫存儲
SQLlite是一款輕量級的關系型數據庫, 作為Android系統內置的數據庫, 它的運算數度非常快,占用資源少,通常只需幾百KB的內存就足夠,SQLite不像其他關系型數據庫擁有眾多繁雜的數據類型,它的數據類型很簡單,integer 表示整型, real表示浮點型, text表示文本類型, bolb表示二進制型。 此處出示一個SQLite數據庫存儲的案例: SQLite...
猜你喜歡
使用Android studio實現SQLite數據庫存儲
使用Android studio實現SQLite數據庫存儲 題目 代碼 XML代碼(1) XML代碼(2) JAVA代碼(1) JAVA代碼(2) JAVA代碼(3) 運行結果 題目 1.要求按圖1完成設計,此界面為啟動界面。其中Spinner中的數據為:語文,數學,英語,歷史,生物。Spinner使用適配器綁定數據。 2.當點擊“添加成績”按鈕時,先判斷SQLite中是否...
數據庫原理讀書筆記
從時間復雜度說起 對于一些普通運算時間復雜度顯得不是那么重要 但是對于應對大量的數據 或者要爭取毫秒級操作 那么理解這個概念就很關鍵了 舉例: 假設要處理2000條數據 O(1) 算法會消耗一次運算 O(log(n)) 算法會消耗7次運算 O(n*log(n)) 算法會消耗 14,000 次運算 O(n^2) 算法會消耗 4,000,000 次運算 hash表的時間復雜度O(1) 平衡二叉樹的時間...
16讀書筆記之文件存儲和SharedPreference存儲
今天學習第六章 荒廢了幾天想想還是看書學習吧,沒有其他的更好的學習方式了。 還是不看視頻學習了。 數據存儲全方案——詳解持久化技術 Android系統中主要提供了三種方式用于簡單地實現數據持久化功能: 當然除了這三種方式外,你還可以將數據保存在手機的SD卡中,不過使用文件,SharedPreference或數據庫保存數據會相對更簡單一些,而且比起將數據保存在SD卡中會更加地...
【筆記】大數據技術之云數據庫存儲(六)
云數據庫 概述 優勢 按需服務 隨時服務 通用性 高可靠性 廉價 超大規模 動態可擴展 安全 易用 高性能 系統架構 UMP系統概述 保持著單一的對外訪問入口 清楚單點故障,保證服務的高可靠性 具有良好的可伸縮性,能夠動態地增加/減少計算資源 實現資源之間的相互隔離 問題: 單個用戶消耗過多 導致對其它用戶產生影響 組件 Mnesia 分布式數據庫管理系統 支持事務,支持透明的數據分片,利用兩階鎖...