數據庫SQL的使用

數據存儲之數據庫SQLite

SQLite簡介

SQLite是一種輕量級的基於文件的數據庫管理系統,是由C語言編寫,實現了標準的SQL中CRUD操作,具有小巧、高效的特點。

SQLite內部支持的數據類型:

  • NULL 值是一個 NULL 值。
  • INTEGER 值是一個帶符號的整數,根據值的大小存儲在 1、2、3、4、6 或 8 字節中。
  • REAL 值是一個浮點值,存儲爲 8 字節的 IEEE 浮點數字。
  • TEXT 值是一個文本字符串,使用數據庫編碼(UTF-8、UTF-16BE 或 UTF-16LE)存儲。
  • BLOB 值是一個 blob 數據,完全根據它的輸入存儲。

和INTEGER親和的數據類型:
  • INT
  • INTEGER
  • TINYINT
  • SMALLINT
  • MEDIUMINT
  • BIGINT
  • UNSIGNED BIG INT
  • INT2
  • INT8

和TEXT親和的數據類型

  • CHARACTER(20)
  • VARCHAR(255)
  • VARYING CHARACTER(255)
  • NCHAR(55)
  • NATIVE CHARACTER(70)
  • NVARCHAR(100)
  • TEXT
  • CLOB

和NONE親和的數據類型

  • BLOB
  • no datatype specified

和REAL親和的數據類型

  • REAL
  • DOUBLE
  • DOUBLE PRECISION
  • FLOAT

和NUMERIC親和的數據類型

  • NUMERIC
  • DECIMAL(10,5)
  • BOOLEAN
  • DATE
  • DATETIME

Boolean 數據類型

SQLite 沒有單獨的 Boolean 存儲類。相反,布爾值被存儲爲整數 0(false)和 1(true)。

Date 與 Time 數據類型

SQLite 沒有一個單獨的用於存儲日期和/或時間的存儲類,但 SQLite 能夠把日期和時間存儲爲 TEXT、REAL 或 INTEGER 值。

存儲類         日期格式
TEXT        格式爲 "YYYY-MM-DD HH:MM:SS.SSS" 的日期。
REAL        從公元前 4714 年 11 月 24 日格林尼治時間的正午開始算起的天數。
INTEGER 從 1970-01-01 00:00:00 UTC 算起的秒數。

您可以以任何上述格式來存儲日期和時間,並且可以使用內置的日期和時間函數來自由轉換不同格式。
更多SQLite內容可以查看SQLite教程


添加數據庫文件到項目中

數據庫文件添加到assets目錄下如圖:

assets:存放資源文件,比方說mp3、視頻文件、數據庫文件

assets

從文件夾中(assets目錄)拷貝數據庫文件(到files目錄)

/**
 * 拷貝數據庫文件
 * @param daName 數據庫db文件 xxx.db
 */
private void copyDB(String daName) {
    //拿到數據庫文件
    //data/data/包名/files/
    File filesDir = getFilesDir();
    Log.d(TAG,"路徑:" + filesDir.getAbsolutePath());
    File destFile = new File(getFilesDir(),daName);//獲取路徑,要拷貝的目標地址

    //數據庫已經存在就不再拷貝
    if(destFile.exists()){
        Log.d(TAG,"數據庫:" + daName + "已存在!");
        return;
    }
    FileOutputStream out = null;
    InputStream in = null;
    try {
        in = getAssets().open(daName);
        out = new FileOutputStream(destFile);

        //讀數據
        int len=0;
        byte[] buffer = new byte[1024];
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            in.close();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

創建及使用數據庫

創建的數據庫在/data/data/包名/databases目錄中

root@android:/data/data/com.jeff.appmanager # ls
ls
cache
databases
lib
root@android:/data/data/com.jeff.appmanager # cd databases
cd databases
root@android:/data/data/com.jeff.appmanager/databases # ls
ls
AppLock.db 數據庫文件
AppLock.db-journal 日誌文件

1.定義自己的SQLiteOpenHelper

SQLiteOpenHelper內部方法

SQLiteOpenHelper_methods

繼承SQLiteOpenHelper的子類必須擁有以下以下三種方法:

  • 構造方法 創建數據庫
  • onCreate() 重寫方法,用於創建表
  • onUpgrade() 重寫方法,用於數據庫的升級

另外還有兩個重要的實例方法:

這兩個方法都可以創建或打開一個現有的數據庫(如果數據庫存在就直接打開,否則就創建一個新的數據庫),並返回一個可對數據庫進行讀寫操作的對象。

  • getReadableDataBase() 返回的對象以只讀的方式打開數據庫
  • getWritableDataBase() 返回的對象對數據庫可讀可寫,但在數據庫不可寫入時會報出異常

書本數據庫實例

public class BookOpenHelper extends SQLiteOpenHelper {

    public static final String CREATE_BOOK = "create table Book ("
            + "id integer primary key autoincrement, "
            + "name text,"
            + "author text, "
            + "pages integer, "
            + "price real)";//1.0
    public static final String CREATE_CATEGORY = "create table Category ("
            + "id integer primary key autoincrement, "
            + "category_name text)";//1.1
    public static final String UPDATE_BOOK = "create table Book ("
            + "id integer primary key autoincrement, "
            + "name text,"
            + "author text, "
            + "pages integer, "
            + "price real,"
            + "category_id integer)";//2.0
    private Context mContext;

    /**
     * 構造方法創建指定name數據庫
     *
     * @param context 上下文
     * @param name    數據庫名稱
     * @param factory 一般爲空
     * @param version 數據庫版本
     */
    public BookOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    /**
     * 構造方法直接構造一個數據庫名BookStore.db的數據庫
     *
     * @param context 上下文
     */
    public BookOpenHelper(Context context) {
        super(context, "BookStore.db", null, 1);
        mContext=context;
    }

    /***
     * 創建數據庫時調用,如果數據庫已存在不調用
     * @param db SQLiteDatabase對象
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        //App版本1.1時加入Category表。若用戶首次建庫兩張表同時建立,若軟件升級會在onUpgrade建立Category表
        db.execSQL(CREATE_BOOK);//數據庫1.0
        db.execSQL(CREATE_CATEGORY);//數據庫1.1
        Toast.makeText(mContext, "數據庫創建成功", Toast.LENGTH_SHORT).show();
    }

    /**
     * 升級數據庫
     *
     * @param db         SQLiteDatabase對象
     * @param oldVersion 數據庫舊版本號
     * @param newVersion 數據庫新版號
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //針對數據庫1.1版本,數據庫一旦存在onCreate方法不再調用,Category表無法在onCreate方法中創建
        //根據數據庫版本執行Category表的創建語句
        switch (oldVersion) {
            case 1:
                db.execSQL(CREATE_CATEGORY);
                break;
            case 2:
                //數據庫2.0 創建Book表,相對1.0版本增加了category_id列
                db.execSQL("alert table Book add column category_id integer");
                break;
            default:
        }

        //過於暴力不建議
//        db.execSQL("drop table if exists Book");
//        db.execSQL("drop table if exists Category");
//        onCreate(db);
    }
}

操作SQLite的主要類SQLiteDataBase

openDatabase()方法,打開指定路徑的數據庫

public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {
    return openDatabase(path, factory, flags, null);
}

insert()方法,插入數據

public long insert(String table, String nullColumnHack, ContentValues values) {
    try {
        return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
    } catch (SQLException e) {
        Log.e(TAG, "Error inserting " + values, e);
        return -1;
    }
}

update()方法,修改數據

public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
    return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE);
}

query()方法,查詢數據

//Query the given table, returning a Cursor over the result set
public Cursor query(String table, String[] columns, String selection,
        String[] selectionArgs, String groupBy, String having,
        String orderBy) {

    return query(false, table, columns, selection, selectionArgs, groupBy,
            having, orderBy, null /* limit */);
}

//Query the given table, returning a Cursor over the result set
public Cursor query(String table, String[] columns, String selection,
        String[] selectionArgs, String groupBy, String having,
        String orderBy, String limit) {

    return query(false, table, columns, selection, selectionArgs, groupBy,
            having, orderBy, limit);
}

delete()方法,刪除數據

public int delete(String table, String whereClause, String[] whereArgs) {
    acquireReference();
    try {
        SQLiteStatement statement =  new SQLiteStatement(this, "DELETE FROM " + table +
                (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
        try {
            return statement.executeUpdateDelete();
        } finally {
            statement.close();
        }
    } finally {
        releaseReference();
    }
}

execSQL()方法,執行SQL語句

//Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE。
public void execSQL(String sql, Object[] bindArgs) throws SQLException {
    if (bindArgs == null) {
        throw new IllegalArgumentException("Empty bindArgs");
    }
    executeSql(sql, bindArgs);
}

//Execute a single SQL statement that is NOT a SELECT
or any other SQL statement that returns data.
public void execSQL(String sql) throws SQLException {
    executeSql(sql, null);
}

rawQuery()方法,使用SQL語句查詢

//Runs the provided SQL and returns a Cursor over the result set.
public Cursor rawQuery(String sql, String[] selectionArgs) {
    return rawQueryWithFactory(null, sql, selectionArgs, null, null);
}

//Runs the provided SQL and returns a Cursor over the result set
public Cursor rawQuery(String sql, String[] selectionArgs,
        CancellationSignal cancellationSignal) {
    return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal);
}

查詢病毒病毒數據庫

public class AntivirusDao {

    public static boolean isVirus(String md5) {
        String path = "/data/data/包名/files/antivirus.db";
        boolean result = false;
        //打開病毒數據庫
        SQLiteDatabase db = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
        Cursor cursor = db.rawQuery("select * from datable where md5=?", new String[]{md5});
        if (cursor.moveToNext()) {
            result = true;
        }
        cursor.close();
        db.close();
        return result;
    }
}

操作書本數據庫(封裝了對數據庫的各種操作方法)

public class BookDao {
    private final String TAG = "BookDao";
    private BookOpenHelper mHelper; //BookOpenHelper實例對象
    private Context mContent;

    /**
     * 構造方法,創建BookOpenHelper實例
     *
     * @param context 上下文
     */
    public BookDao(Context context) {
        this.mHelper = new BookOpenHelper(context);
        mContent=context;
    }

    /**
     * 添加數據
     * @param name
     * @param author
     * @param pages
     * @param price
     */
    public void add(String name,String author,int pages,float price) {
        SQLiteDatabase db = mHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        // 開始組裝第一條數據
        values.put("name", name);
        values.put("author", author);
        values.put("pages", pages);
        values.put("price", price);
        db.insert("Book", null, values);
        Toast.makeText(mContent, "數據添加成功", Toast.LENGTH_SHORT).show();
//        values.clear();
//        // 開始組裝第二條數據
//        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);
        db.close();
    }

    /**
     * 修改數據
     *
     * @param id     數據id
     * @param name   書名
     * @param author 作者
     * @param pages  頁數
     * @param price  價格
     */
    public void update(int id, String name, String author, int pages, float price) {
        SQLiteDatabase db = mHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("name", name);
        values.put("author", author);
        values.put("pages", pages);
        values.put("price", price);
        db.update("Book", values, "id=?", new String[]{String.valueOf(id)});
        Toast.makeText(mContent, "數據修改成功", Toast.LENGTH_SHORT).show();
        db.close();
    }

    /**
     * 刪除數據
     * db.delete()
     * @param table       表名
     * @param whereClause 約束條件
     * @param whereArgs   約束值
     */
    public void delete(int id) {
        SQLiteDatabase db = mHelper.getWritableDatabase();
        db.delete("Book", "id=?", new String[]{String.valueOf(id)});
        Toast.makeText(mContent, "刪除成功", Toast.LENGTH_SHORT).show();
        db.close();
    }

    /**
     * 查詢數據庫中全部數據
     * db.query()
     * @param table         表名
     * @param columns       指定列名
     * @param selection     約束條件
     * @param selectionArgs 約束值
     * @param groupBy       groupBy
     * @param having        having
     * @param orderBy       orderBy
     */
    public List<BookBean> searchAll() {

        //查詢數據庫內容,返回只讀類型的SQLiteDatabase對象
        SQLiteDatabase db = mHelper.getReadableDatabase();
        //打開指定路徑的數據庫如: path = "/data/data/包名/files/antivirus.db"
//        SQLiteDatabase db = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);

        List<BookBean> bookList = new ArrayList<>();
        Cursor cursor = db.query("Book", null, null, null, null, null, null);
        if (cursor.moveToFirst()) {
            do {
                //遍歷Cursor對象
                int id = cursor.getInt(cursor.getColumnIndex("id"));
                String name = cursor.getString(cursor.getColumnIndex("name"));
                String author = cursor.getString(cursor.getColumnIndex("author"));
                int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                float price = cursor.getFloat(cursor.getColumnIndex("price"));
                Log.d(TAG, "searchAll: " + id + "  " + name + "  " + author + "  " + pages + "  " + price);
                BookBean book = new BookBean();
                book.setId(id);
                book.setName(name);
                book.setAuthor(author);
                book.setPages(pages);
                book.setPrice(price);
                bookList.add(book);
            } while (cursor.moveToNext());
        }
        cursor.close();
        db.close();
        return bookList;
    }

    //**************************************************************
    //使用SQL操作數據庫

    /**
     * 添加數據,更新數據,刪除數據
     *
     * @param sql      SQL語句
     * @param bindArgs 一般爲空
     */
    public void execSQL(String sql, String bindArgs) {
        SQLiteDatabase db = mHelper.getWritableDatabase();
        db.execSQL(sql, new String[]{bindArgs});
        db.close();
    }

    /**
     * 重載方法執行SQL語句
     * @param sql
     */
    public void execSQL(String sql) {
        SQLiteDatabase db = mHelper.getWritableDatabase();
        db.execSQL(sql);
        db.close();
    }


    /**
     * 使用SQL語句查詢數據
     *
     * @param sql           SQL語句
     * @param selectionArgs 約束值
     */
    public void rawQuery(String sql, String selectionArgs) {
        SQLiteDatabase db = mHelper.getReadableDatabase();
        Cursor cursor=db.rawQuery(sql, new String[]{selectionArgs});
        if (cursor.moveToFirst()) {
            do {
                //遍歷Cursor對象
                int id = cursor.getInt(cursor.getColumnIndex("id"));
                String name = cursor.getString(cursor.getColumnIndex("name"));
                String author = cursor.getString(cursor.getColumnIndex("author"));
                int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                float price = cursor.getFloat(cursor.getColumnIndex("price"));
                Log.d(TAG, "rawQuery: " + id + "  " + name + "  " + author + "  " + pages + "  " + price);
            } while (cursor.moveToNext());
        }
        cursor.close();
        db.close();
    }

    /**
     * 重載方法,使用SQL語句查詢
     * @param sql
     */
    public void rawQuery(String sql) {
        SQLiteDatabase db = mHelper.getReadableDatabase();
        Cursor cursor=db.rawQuery(sql, null);
        if (cursor.moveToFirst()) {
            do {
                //遍歷Cursor對象
                int id = cursor.getInt(cursor.getColumnIndex("id"));
                String name = cursor.getString(cursor.getColumnIndex("name"));
                String author = cursor.getString(cursor.getColumnIndex("author"));
                int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                float price = cursor.getFloat(cursor.getColumnIndex("price"));
                Log.d(TAG, "rawQuery: " + id + "  " + name + "  " + author + "  " + pages + "  " + price);
            } while (cursor.moveToNext());
        }
        cursor.close();
        db.close();
    }

}

**在activity中調用
dao = new BookDao(this);即可創建數據庫,並通過dao對象對數據庫執行操作**


Cursor對象(查詢數據庫返回的對象)

這是一個接口,該接口爲數據庫查詢返回的結果集提供隨機讀寫訪問

從Cursor對象中讀取數據:

XXX name= cursor.getXXX(getColumnIndex(String columnName));
兩個重要方法:
int getColumnIndex(String columnName);

XXX getXXX(int columnIndex);

XXX getXXX(int columnIndex)方法具體有:

  • String getString(int columnIndex);
  • short getShort(int columnIndex);
  • int getInt(int columnIndex);
  • long getLong(int columnIndex);
  • float getFloat(int columnIndex);
  • double getDouble(int columnIndex);

實例

Cursor cursor=db.rawQuery(sql, null);
    if (cursor.moveToFirst()) {
        do {
            //遍歷Cursor對象
            int id = cursor.getInt(cursor.getColumnIndex("id"));
            String name = cursor.getString(cursor.getColumnIndex("name"));
            String author = cursor.getString(cursor.getColumnIndex("author"));
            int pages = cursor.getInt(cursor.getColumnIndex("pages"));
            float price = cursor.getFloat(cursor.getColumnIndex("price"));
            Log.d(TAG, "rawQuery: " + id + "  " + name + "  " + author + "  " + pages + "  " + price);
        } while (cursor.moveToNext());
    }
    cursor.close();//最後需要關閉cursor
發佈了36 篇原創文章 · 獲贊 20 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章