Android 數據存儲提供了四種存儲方式:java
Shared Preferencesandroid
使用鍵值對(Map(key, value))來存儲數據
Internal Storagesql
內部存儲,存儲在設備內存的 私人數據
External Storageshell
外部存儲,存儲在外部設備的 公共數據
SQLite Databases數據庫
存儲在關係型數據庫;SQLite 是相似MySQL 的關係型數據庫,由於其體較小,功能全,被運用在了大多嵌入式設備
Network Connectionapp
很是小的關係型數據庫ide
import android.app.Activity; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class SimpleActivity extends Activity { private static final String INFO = "SimpleActivity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_layout); Log.i(INFO, INFO); SQLiteDatabase db = openOrCreateDatabase("simple.db", Context.MODE_PRIVATE, null); db.execSQL("DROP TABLE IF EXISTS Person"); // 建立表 db.execSQL("CREATE TABLE Person (" + " id INTEGER PRIMARY KEY AUTOINCREMENT," + " name varchar(30)," + " age SMALLINT" + ")"); Log.d(INFO, "Create Table Successful"); Person person = new Person(); person.name = "Tikitoo"; person.age = 23; // 插入數據 db.execSQL("INSERT INTO Person VALUES(NULL , ?, ?)", new Object[]{person.name, person.age}); Log.d(INFO, "Insert Successful"); person.name = "Davin"; person.age = 30; ContentValues cv = new ContentValues(); cv.put("name", person.name); cv.put("age", person.age); // 插入ContentValue 中的數據 db.insert("Person", null, cv); Log.d(INFO, "ContentValues Insert Successful"); cv = new ContentValues(); cv.put("age", 35); // 更新數據 db.update("Person", cv, "name = ?", new String[]{"Davin"}); Log.d(INFO, "Update Successful"); Cursor cursor = db.rawQuery("SELECT * FROM Person", null); while (cursor.moveToNext()) { int id = cursor.getInt(cursor.getColumnIndex("id")); String name = cursor.getString(cursor.getColumnIndex("name")); int age = cursor.getInt(cursor.getColumnIndex("age")); Log.d("INFO", id + name + age); } Log.d(INFO, "Query Successful"); cursor.close(); db.delete("Person", "age < ?", new String[]{"25"}); Log.d(INFO, "Delete Successful"); db.close(); // deleteDatabase("tikitoo_sqlite.db"); } }
參考:工具
Android SQLite Database Tutorial
Android中SQLite應用詳解 - scott's blog - 博客頻道 - CSDN.NETui
使用SQLite 調試工具ADB(adb)this
(android:adb環境變量的配置)[http://blog.csdn.net/huangbiao86/article/details/6664779]
使用ADB 工具查看adb shell
cd data,ls 出現錯誤,這是,輸入su 回車便可,會請求訪問權限,在手機贊成一下;
adb opendir failed ,permission denied
固然Android 對於SQLite 處理封裝的對象 SQLiteOpenHelper 來返回 SQLiteDatabase 對象來實現增刪改查
咱們再開發的時候,不能像上面寫得那麼簡單,須要對封裝一個子類,提供SQLiteOpenHelper 對象;
package com.tikitoo.android.sqlite.util; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** * Created by Tikitoo1 on 2014/11/12. */ public class DBHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "test.db"; private static final int DATABASE_VERSION = 1; public DBHelper(Context context) { // 設置SQLiteDatabase.CursorFactory 爲null super(context, DATABASE_NAME, null, DATABASE_VERSION); } // 數據庫第一次建立被調用 @Override public void onCreate(SQLiteDatabase db) { // 初始化建立一個表 db.execSQL("CREATE TABLE IF NOT EXISTS Person" + "(id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar(30), age SMALLINT"); } // 若是數據庫版本改變,則會調用 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 新增一個字段 db.execSQL("ALTER TABLE Person ADD COLUMN other STRING"); } }
DatabaseSQLite 對象實現對數據庫的增刪改查
import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.util.Log; import java.util.ArrayList; import java.util.List; public class DBManager { private static final String INFO = DBManager.class.toString(); private DBHelper helper; private SQLiteDatabase db; public DBManager(Context context) { helper = new DBHelper(context); db = helper.getWritableDatabase(); // helper.getReadableDatabase(); } // 新增一條數據,將數據存在Person 對象,在放在List 集合中,遍歷集合,能夠實現多條數據插入; public void add(List<Person> persons) { db.beginTransaction(); try { for (Person person : persons) { db.execSQL("INSERT INTO Person VALUES(NULL, ?, ?, ?)", new Object[]{person.name, person.age, person.info}); } // 設置事物 db.setTransactionSuccessful(); } finally { // 結束事物 db.endTransaction(); } } // 更新一條數據,經過name 來修改age public void update(Person person) { ContentValues cv = new ContentValues(); cv.put("age", person.age); cv.put("info", person.info); // 參數,(表名, ContentValues 對象, where 條件,where 條件對應的值) db.update("Person",cv, "name = ?", new String[]{person.name}); } public void delete(Person person) { db.delete("Person", "age >= ?", new String[]{"" + person.age});// String.valueOf(person.age); } public List<Person> person() { List<Person> lists = new ArrayList<Person>(); // 使用rawQuery() 方法,返回遊標對象,遍歷出數據庫的數據 Cursor cursor = db.rawQuery("SELECT * FROM Person", null); while (cursor.moveToNext()) { int _id = cursor.getInt(cursor.getColumnIndex("id")); String name = cursor.getString(cursor.getColumnIndex("name")); int age = cursor.getInt(cursor.getColumnIndex("age")); String info = cursor.getString(cursor.getColumnIndex("info")); Log.i(INFO, new Person(_id, name, age, info).toString()); } return lists; } // 關閉數據庫 public void closeDB() { db.close(); } }
對了還有將數據表使用JavaBean 處理,將數據存儲在Person 對象,比較方便
public class Person { public int _id; // id,惟一標識 public String name; // 姓名 public int age; // 年齡 public String info; // 備註信息 public Person() { } public Person(String name, int age, String info) { this.name = name; this.age = age; this.info = info; } public Person(int _id, String name, int age, String info) { this._id = _id; this.name = name; this.age = age; this.info = info; } // 重寫toString() 方法 @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Person[ "); sb.append("name = " + this.name); // sb.append("; id = " + _id); sb.append("; age = " + this.age); sb.append("; info = " + this.info); sb.append(" ]"); return sb.toString(); } }
首先判斷數據庫實例是不是打開狀態,
若是是,則打開一個可讀寫的數據庫實例;
若是遇到磁盤已滿,獲取失敗,再以可讀模式打開數據庫,返回數據庫實例
若是不爲空,已經打開,並非以只讀模式打開的,
若是mDatabase 不爲空則加鎖,而後建立或打開新的數據庫實例,比較版本,爲數據庫設置新的版本號,最後把不爲空的mDatabase 解鎖,把新建立的數據庫實例賦值給 mDatabase,並返回新的實例;
因此,若是不遇到磁盤已滿的狀況下,兩個方式返回的數據庫實例是同樣的,若是擔憂這種方式發生,先調用 getWritableDatabase 方法, 若是異常,則在調用 getReadableDatabase ,固然這個時候的數據庫實例是隻讀的