[Android]SQLite的使用

Android 數據存儲提供了四種存儲方式:java

  • Shared Preferencesandroid

    使用鍵值對(Map(key, value))來存儲數據
  • Internal Storagesql

    內部存儲,存儲在設備內存的 私人數據
  • External Storageshell

    外部存儲,存儲在外部設備的 公共數據
  • SQLite Databases數據庫

    存儲在關係型數據庫;SQLite 是相似MySQL 的關係型數據庫,由於其體較小,功能全,被運用在了大多嵌入式設備

Network Connectionapp

SQLite 簡介

很是小的關係型數據庫ide

SQLiteOpenHelper

CRUD(增刪改查)

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 對象;

封裝的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();
    }
}

getReadableDatabase() 和getWritableDatabase() 方法的區別:

getReadableDatabase:

首先判斷數據庫實例是不是打開狀態,
若是是,則打開一個可讀寫的數據庫實例;
若是遇到磁盤已滿,獲取失敗,再以可讀模式打開數據庫,返回數據庫實例

getWritableDatabase:

若是不爲空,已經打開,並非以只讀模式打開的,
若是mDatabase 不爲空則加鎖,而後建立或打開新的數據庫實例,比較版本,爲數據庫設置新的版本號,最後把不爲空的mDatabase 解鎖,把新建立的數據庫實例賦值給 mDatabase,並返回新的實例;

總結

因此,若是不遇到磁盤已滿的狀況下,兩個方式返回的數據庫實例是同樣的,若是擔憂這種方式發生,先調用 getWritableDatabase 方法, 若是異常,則在調用 getReadableDatabase ,固然這個時候的數據庫實例是隻讀的

相關文章
相關標籤/搜索