1. 程式人生 > >【Android】資料儲存資料庫SQLite(之前有看到的一篇關於SQLite文章,簡單明瞭、覆蓋較全面適合學習)

【Android】資料儲存資料庫SQLite(之前有看到的一篇關於SQLite文章,簡單明瞭、覆蓋較全面適合學習)

一:前言

之前介紹過Android中儲存資料的兩種方式:SharedPreferencesFile,這篇介紹另一種儲存資料的方式——資料庫SQLite——輕量級資料庫系統。

資料庫簡單來說可視為電子化的檔案櫃——儲存電子檔案的處所,使用者可以對檔案中的資料執行新增、擷取、更新、刪除等操作


二:用法

舉一個儲存使用者資訊的栗子:
建立一個數據庫mySQLite,在該資料庫中建立一個user表,用來儲存使用者資訊,使用者屬性name(姓名:String型別)、age(年齡:int型別)。

1、建立一個使用者類(方便後面的操作)

/**
 * 使用者
 * 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;
    }
}


2、建立一個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)屬性。

3、操作資料庫

操作資料庫,增刪查改是免不了的。下面的方法都是在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()

  • 改(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指令,至於複雜的自己去查吧

4、輔助類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對資料的操作十分靈活,不過相比SharedPreferencesFile在使用上要複雜一些,而且要一點的資料庫基礎。

附: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;
        }
    }
}