【Android】資料儲存(三) 資料庫(SQLite)
前言
之前介紹過Android中儲存資料的兩種方式:SharedPreferences和File,這篇介紹另一種儲存資料的方式——資料庫。
資料庫:簡單來說可視為電子化的檔案櫃——儲存電子檔案的處所,使用者可以對檔案中的資料執行新增、擷取、更新、刪除等操作。
想必大家對資料庫都不陌生,想當年上資料庫課的時候,被那些命令整得不要不要的。
扯遠了...
進入正題,在Android開發的過程中,儲存資料是難免的。如果資料量較小的時候可用SharedPreferences或File來儲存,當資料量較大且關係複雜的時候就要用到Android中的資料庫SQLite——輕量級資料庫系統。
用法
舉一個儲存使用者資訊的栗子:
建立一個資料庫mySQLite,在該資料庫中建立一個user表,用來儲存使用者資訊,使用者屬性name(姓名:String型別)、age(年齡:int型別)。
建立一個使用者類(方便後面的操作)
/**
* 使用者
* Created by Gavin on 2016/5/30.
*/
public class User {
/**
* id
*/
private int id;
/**
* 使用者名稱
*/
private String name;
/**
* 年齡
*/
private int age;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
建立一個DatabaseHelper類
用來處理所有的資料庫操作。(這用到了SQL語句,不懂的看解釋)
/**
* Created by Gavin on 2016/5/30.
*/
public class DatabaseHelper extends SQLiteOpenHelper {
/**
* 資料庫版本,需要升級資料庫時只要加一即可
*/
private static final int DATABASE_VERSION = 1;
/**
* 資料庫名
*/
private static final String DATABASE_NAME = "mySQLite.db";
/**
* 構造方法
* 每次建立DatabaseHelper物件時,若本應用無該資料庫,則新建資料庫並呼叫onCreate方法;
* 若該資料庫已建立則直接使用已存在的資料庫且跳過onCreate方法
* @param context 上下文
*/
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/**
* 建立資料庫是時呼叫(只被呼叫一次)
* @param db 資料庫
*/
@Override
public void onCreate(SQLiteDatabase db) {
//建立user表,屬性:id(使用者id,主鍵)、name(姓名)、age(年齡)
db.execSQL("CREATE TABLE user (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(10),age INTEGER)");
}
/**
* 跟新資料庫時呼叫
* @param db 資料庫
* @param oldVersion 舊版本號
* @param newVersion 新版本號
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//升級:往user表,新增性別屬性
//db.execSQL("ALTER TABLE user ADD COLUMN gender VARCHAR(2)");
}
}
資料庫mySQLite在構造方法中建立,其中super()的引數有4個:
context:上下文;
datebaseName:資料庫名,一般以.db結尾;
factory : 當開啟的資料庫執行查詢語句的時候 會建立一個Cursor物件, 這時會呼叫Cursor工廠類 factory, 可以填寫null預設值;
version:資料庫版本,需要升級資料庫時將版本號加一,將升級的內容寫在onUpgrade中即可。
- onCreate
當資料庫第一次建立的時候,會執行onCreate()方法。這裡的onCreate方法中建立了一張user表,db.execSQL()方法執行了裡面SQL語句。
- onUpgrade
資料庫升級時會呼叫onUpgrade()方法,這裡的onUpgrade()方法往user表中新增了性別(gender)屬性。
運算元據庫
運算元據庫,增刪查改是免不了的。下面的方法都是在DatabaseHelper 中新增。
- 增(Create)
/**
* 插入一條資料
* @param user 使用者物件
*/
public void insertAUser(User user) {
//如果要對資料進行更改,就呼叫此方法得到用於運算元據庫的例項,
//該方法以讀和寫方式開啟資料庫
SQLiteDatabase database = getWritableDatabase();
//向user表插入一條資料
database.execSQL(
"INSERT INTO user(name, age) VALUES(?,?)",
new Object[]{user.getName(), user.getAge()});
}
insertAUser()中使用了execSQL()執行了插入資料的操作。
這裡用到的execSQL()有兩個引數:
引數1:SQL指令,這裡是一條插入命令,命令中的問號(?)為佔位符
引數2:Object陣列,陣列中的內容對應引數1中的問號(?)
- 刪(Delete)
/**
* 根據id刪除一條資料
* @param id 使用者id
*/
public void deleteAUser(Integer id) {
SQLiteDatabase database = getWritableDatabase();
//根據id刪除一條資料
database.execSQL("DELETE FROM user WHERE id=?",
new Object[]{id});
}
deleteAUser()根據使用者id,刪除了對應的使用者資訊。這裡也是用了execSQL()執行資料操作。
- 查(Read)
/**
* 讀取一條資料
* @param id 使用者id
* @return 使用者物件
*/
public User readAUser(Integer id) {
//如果只對資料進行讀取,建議使用此方法
SQLiteDatabase database = getReadableDatabase();
Cursor cursor = database.rawQuery(
"SELECT * FROM user WHERE id=?",
new String[]{id.toString()});
if (cursor.moveToFirst()) {
//讀取資料,並返回
User user = new User();
user.setId(cursor.getInt(cursor.getColumnIndex("id")));
user.setName(cursor.getString(cursor.getColumnIndex("name")));
user.setAge(cursor.getInt(cursor.getColumnIndex("age")));
cursor.close();
return user;
} else {
//未讀出資料,返回空資料
return null;
}
}
/**
* 獲取整個使用者列表
* @return
*/
public List<User> readAllUser() {
SQLiteDatabase database = getReadableDatabase();
Cursor cursor = database.rawQuery("SELECT * FROM user", new String[]{});
List<User> list = new ArrayList<User>();
//使用moveToNext()逐條讀取
while (cursor.moveToNext()) {
User user = new User();
user.setId(cursor.getInt(cursor.getColumnIndex("id")));
user.setName(cursor.getString(cursor.getColumnIndex("name")));
user.setAge(cursor.getInt(cursor.getColumnIndex("age")));
list.add(user);
}
cursor.close();
return list;
}
readAUser()中使用rawQuery方法獲取到使用者資訊,通過cursor.moveToFirst()來獲取cursor的第一條資料,接著通過cursor.getInt()、cursor.getString()來獲取對應的資料。
這裡使用了getReadableDatabase()而不是getWritableDatabase()
- Cursor
是每行的集合。詳情請參考Android 中關於 【Cursor】 類的介紹
- 改(Update)
/**
* 更新一條使用者資料
* @param user 使用者物件
*/
public void updateAUser(User user) {
SQLiteDatabase database = getWritableDatabase();
//根據id更新一條資料
database.execSQL(
"UPDATE user SET name=?, age=? WHERE id=?",
new Object[]{user.getName(), user.getAge(), user.getId()});
}
這也沒什麼好說的~~
execSQL()中用到的都最基礎的是SQL指令,至於複雜的自己去查吧
使用
輔助類DatabaseHelper寫完了,接下來就是使用了
- 插入一條資料
DatabaseHelper helper = new DatabaseHelper(this);
User user1 = new User();
user1.setName("lisa");
user1.setAge(20);
helper.insertAUser(user1);//插入一條資料
Log.i(TAG, helper.readAllUser().toString());//檢視所有使用者
結果
- 根據id獲取一條資料,修改,刪除。上面我們看到,插入的那條資料id是1
DatabaseHelper helper = new DatabaseHelper(this);
User user1 = helper.readAUser(1); //查詢id為1的使用者
Log.i(TAG, helper.readAUser(1).toString()); //顯示id為1的使用者
user1.setAge(30); //將年齡改為30
helper.updateAUser(user1); //更新資料庫
Log.i(TAG, helper.readAUser(1).toString()); //顯示id為1的使用者
helper.deleteAUser(user1.getId()); //刪除user1
Log.i(TAG, helper.readAUser(1).toString()); //顯示id為1的使用者
結果
上面的程式碼中,分別列印了三次log。
第一次使用id為1的使用者;
第二次是年齡被修改為30的使用者;
第三次是被刪除的使用者,因為使用者不存在了,所以沒有第三條log
(由於helper.readAUser(1)沒有獲取到資料,返回null,接著使用了toString()出現空指標異常,閃退了,做了一個反面教材~~)。
不管怎麼說,這次的目的達到了,增刪查改都ok了。
小結
使用SQLite就是在本地建了一個資料庫,使用資料庫中的表來儲存資料。SQLite對資料的操作十分靈活,不過相比SharedPreferences和File在使用上要複雜一些,而且要一點的資料庫基礎。
附:DatabaseHelper完整程式碼
package com.nostra13.universalimageloader.sample;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Gavin on 2016/5/30.
*/
public class DatabaseHelper extends SQLiteOpenHelper {
/**
* 資料庫版本,需要升級資料庫時只要加一即可
*/
private static final int DATABASE_VERSION = 1;
/**
* 資料庫名
*/
private static final String DATABASE_NAME = "mySQLite.db";
/**
* 構造方法
* 每次建立DatabaseHelper物件時,若本應用無該資料庫,則新建資料庫並呼叫onCreate方法;
* 若該資料庫已建立則直接使用已存在的資料庫且跳過onCreate方法
* factory : 當開啟的資料庫執行查詢語句的時候 會建立一個Cursor物件, 這時會呼叫Cursor工廠類 factory, 可以填寫null預設值
* @param context 上下文
*/
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/**
* 建立資料庫是時呼叫(只被呼叫一次)
* @param db 資料庫
*/
@Override
public void onCreate(SQLiteDatabase db) {
//建立user表,屬性:id(使用者id,主鍵)、name(姓名)、age(年齡)
db.execSQL("CREATE TABLE user (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(10),age INTEGER)");
}
/**
* 跟新資料庫時呼叫
* @param db 資料庫
* @param oldVersion 舊版本號
* @param newVersion 新版本號
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//升級user表,新增性別
//db.execSQL("ALTER TABLE user ADD COLUMN gender VARCHAR(2)");
}
/**
* 插入一條資料
* @param user 使用者物件
*/
public void insertAUser(User user) {
//如果要對資料進行更改,就呼叫此方法得到用於運算元據庫的例項,該方法以讀和寫方式開啟資料庫
SQLiteDatabase database = getWritableDatabase();
//向user表插入一條資料
database.execSQL(
"INSERT INTO user(name, age) VALUES(?,?)",
new Object[]{user.getName(), user.getAge()});
}
/**
* 更新一條使用者資料
* @param user 使用者物件
*/
public void updateAUser(User user) {
SQLiteDatabase database = getWritableDatabase();
//根據id更新一條資料
database.execSQL(
"UPDATE user SET name=?, age=? WHERE id=?",
new Object[]{user.getName(), user.getAge(), user.getId()});
}
/**
* 根據id刪除一條資料
* @param id 使用者id
*/
public void deleteAUser(Integer id) {
SQLiteDatabase database = getWritableDatabase();
//根據id刪除一條資料
database.execSQL("DELETE FROM user WHERE id=?",
new Object[]{id});
}
/**
* 獲取整個使用者列表
* @return
*/
public List<User> readAllUser() {
SQLiteDatabase database = getReadableDatabase();
Cursor cursor = database.rawQuery("SELECT * FROM user", new String[]{});
List<User> list = new ArrayList<User>();
while (cursor.moveToNext()) {
User user = new User();
user.setId(cursor.getInt(cursor.getColumnIndex("id")));
user.setName(cursor.getString(cursor.getColumnIndex("name")));
user.setAge(cursor.getInt(cursor.getColumnIndex("age")));
list.add(user);
}
cursor.close();
return list;
}
/**
* 讀取一條資料
* @param id 使用者id
* @return 使用者物件
*/
public User readAUser(Integer id) {
//如果只對資料進行讀取,建議使用此方法
SQLiteDatabase database = getReadableDatabase();
Cursor cursor = database.rawQuery(
"SELECT * FROM user WHERE id=?",
new String[]{id.toString()});
if (cursor.moveToFirst()) {
//讀取資料,並返回
User user = new User();
user.setId(cursor.getInt(cursor.getColumnIndex("id")));
user.setName(cursor.getString(cursor.getColumnIndex("name")));
user.setAge(cursor.getInt(cursor.getColumnIndex("age")));
cursor.close();
return user;
} else {
//未讀出資料,返回空資料
return null;
}
}
}
相關文章
- IOS資料儲存之Sqlite資料庫iOSSQLite資料庫
- android sqlite資料庫 新增資料AndroidSQLite資料庫
- Android資料儲存之SQLCipher資料庫加密AndroidSQL資料庫加密
- Android資料儲存之Sqlite的介紹及使用AndroidSQLite
- Android 中使用 SQLite 資料庫AndroidSQLite資料庫
- 【資料庫】資料庫儲存過程(一)資料庫儲存過程
- 列式儲存資料庫資料庫
- IOS資料儲存之FMDB資料庫iOS資料庫
- sqlite 資料庫的資料字典SQLite資料庫
- MySQL 資料庫儲存引擎MySql資料庫儲存引擎
- 資料庫儲存過程資料庫儲存過程
- MySQL 更改資料庫資料儲存目錄MySql資料庫
- 明解資料庫------資料庫儲存演變史資料庫
- 【資料庫】資料庫儲存元素型別基礎資料庫型別
- 理一下 iOS 本地持久化儲存(側重資料庫SQLite)iOS持久化資料庫SQLite
- Flutter持久化儲存之資料庫儲存Flutter持久化資料庫
- Android中的資料儲存Android
- 33.Android資料儲存Android
- Android 封裝AsyncTask操作Sqlite資料庫Android封裝SQLite資料庫
- 資料儲存的三種方式
- sqlite操作--- oracle資料庫中的資料導進sqliteSQLiteOracle資料庫
- 儲存過程呼叫不同資料庫的資料儲存過程資料庫
- 報表資料分庫儲存
- MySql資料庫——儲存過程MySql資料庫儲存過程
- MySQL資料庫操作、儲存引擎MySql資料庫儲存引擎
- gitlab資料庫儲存位置Gitlab資料庫
- 使用Room持久庫儲存資料OOM
- 管理資料庫儲存結構資料庫
- 儲存與資料庫系統資料庫
- 重新學習Mysql資料庫3:Mysql儲存引擎與資料儲存原理MySql資料庫儲存引擎
- 資料儲存
- Android中的資料儲存之檔案儲存Android
- Sql Server資料庫資料匯入到SQLite資料庫中Server資料庫SQLite
- 【Java】操作Sqlite資料庫JavaSQLite資料庫
- Android實用的SQLite資料庫工具類AndroidSQLite資料庫
- Android資料庫高手祕籍(1):SQLite命令Android資料庫SQLite
- Android資料庫高手祕籍(一):SQLite命令Android資料庫SQLite
- 在Android中檢視和管理sqlite資料庫AndroidSQLite資料庫