Android關於SqList數據庫的使用和封裝

對於開發者來說肯定都對於數據庫不會陌生,今天就來分享一篇關於android的數據庫的一些操作和簡單封裝 ,好,廢話不多說,直接上代碼(大部分解釋都註釋在代碼中了)

MySQLiteOpenHelper.java

public class MySQLiteOpenHelper extends SQLiteOpenHelper {
    private static MySQLiteOpenHelper helper;
    public static final String DB_NAME = "Topeasy.db";// 數據庫名稱
    public static final int VERSION = 1;
    /**
     * 支持創建持數據表時判斷是否存在,存在則不創建,不存在則創建,相應語句如下:
     * create table if not exists
     * MySQL官方對CREATE TABLE IF NOT EXISTS SELECT給出的解釋是:
     * CREATE TABLE IF NOT EXIST… SELECT的行爲,先判斷表是否存在,
     * 如果存在,語句就相當於執行insert into select;
     * 如果不存在,則相當於create table … select。
     * 解析: 1)integer 表示整型, 2)real 表示浮點型, 3)text 表示文本類型, 4)blob
     * 表示二進制類型。
     * 爲了確保數據的完整性和一致性,在創建表時指定字段名稱,字段類型和字段屬性外,還需要使用約束(constraint),
     * 索引 (index),主鍵(primary key)和外鍵(foregin key)等。
     * 約束條件:
     *   not null 非空約束
     *   unique 唯一性約束
     *   primary key 主鍵約束
     *   foreign key 外鍵約束
     *   check 檢查約束
     *   auto_increment 自動標識列(值會自動增1)
     */
    public static final String CREATE_CUSTOMER = "create table " + TableConfig.TABLE_CUSTOMER + " ("
            + "id integer not null primary key autoincrement,"
            + TableConfig.Customer.CUSTOMER_NAME + " verchar(20),"
            + TableConfig.Customer.DELIVERY_PHONE + " verchar(20),"
            + TableConfig.Customer.ADDR + " verchar(20) ,"
            + TableConfig.Customer.ACCESS_TYPE + " verchar(20),"
            + TableConfig.Customer.CUSTOMER_RATING + " verchar(20), "
            + TableConfig.Customer.LAYERS + " verchar(20),"
            + TableConfig.Customer.CONTACTS + " verchar(20),"
            + TableConfig.Customer.REMARK + " verchar(20))";

    //構造器,傳入四個參數Context對象,數據庫名字name,操作數據庫的Cursor對象,版本號version。
    private MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    //爲了簡化構造器的使用,我們自定義一個構造器
    private MySQLiteOpenHelper(Context context, String name) {
        this(context, name, null, VERSION);//傳入Context和數據庫的名稱,調用上面那個構造器
    }

    //將自定義的數據庫創建類單例。 synchronize單例 防止多線程同時那啥  雙重鎖定
    public static MySQLiteOpenHelper getInstance(Context context) {
        if (helper == null) {
            synchronized (MySQLiteOpenHelper.class) {
                if (helper == null)
                    helper = new MySQLiteOpenHelper(context, DB_NAME);//數據庫名稱爲create_db。
            }
        }
        return helper;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //在創建數據庫時,初始化創建數據庫中包含的數據庫表。這裏以一個“客戶”的數據表爲例
        /*
         customer   創建 "客戶"數據表
         */
        db.execSQL(CREATE_CUSTOMER);// 執行sql語句
    }

    /**
     * 對數據庫進行升級,注意: switch 中每一個 case的最後都是沒有使用 break ,
     * 這是爲了保證在跨版本升級的時候,每一次的數據庫修改都能被全部執行到
     *    //當打開數據庫時傳入的版本號與當前的版本號不同時會調用該方法。
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //switch (oldVersion) {
        //   case 1:
        //        db.execSQL(CREATE_CUSTOMER);
        //       APP.mToast("更新數據庫,舊版本是" + oldVersion);
        //   case 2:
        //       db.execSQL(CREATE_CUSTOMER);
        //        APP.mToast("更新數據庫,舊版本是" + oldVersion);
        //    default:
        // }
        db.execSQL("drop table if exists "+TableConfig.TABLE_CUSTOMER); // 如果存在表Book,則刪除該表
        onCreate(db); // 重新調用onCreate(),創建表
    }

代碼中註釋已經解釋的好清楚了,就不多bb了好吧


DbManager.java

import android.database.sqlite.SQLiteDatabase;

import com.my_movingbricks.app.APP;

/**
 * TP0826   創建數據庫類
 * Created by 搬磚小能手 on 2017/4/6.
 * E-mail:[email protected].
 * Signature:當你的才華滿足不了你的野心的時候,那麼你應該靜下心來學習.
 * Alert:語言的巨人,行動的矮子!
 */
public class DbManager {
    private static DbManager manager;
    private MySQLiteOpenHelper mySQLiteOpenHelper;
    private SQLiteDatabase db;

    /**
     * 私有化構造器
     *
     */
    private DbManager() {
        //創建數據庫
        mySQLiteOpenHelper = MySQLiteOpenHelper.getInstance(APP.getInstance());
        if (db == null) {
            db = mySQLiteOpenHelper.getWritableDatabase();
        }
    }

    /**
     * 單例DbManager類
     *
     * @return 返回DbManager對象
     */
    public static DbManager newInstances() {
        if (manager == null) {
            synchronized (DbManager.class) {
                if (manager == null) {
                    manager = new DbManager();
                }
            }
        }
        return manager;
    }

    /**
     * 獲取數據庫的對象
     *
     * @return 返回SQLiteDatabase數據庫的對象
     */
    public SQLiteDatabase getDataBase() {
        return db;
    }

    /**
     * 關閉數據庫
     */
    public void close() {
        mySQLiteOpenHelper.close();
        mySQLiteOpenHelper = null;
        db.close();
        db = null;
        manager = null;
    }

}

初始化數據庫,關閉等等。。


ChannelDaoInface.java


import java.util.ArrayList;

public interface ChannelDaoInface<T> {
    /**
     * 插入一條數據
     *
     * @param item 傳進來的item
     * @return 是否插入成功
     */
    public boolean addCache(String tableName, T item);

    /**
     * 刪除一條數據
     *
     * @param tableName   刪除數據庫的表名
     * @param whereClause "url=?"; 刪除的字段名
     * @param whereArgs   {name} 刪除的字段的值
     * @return
     */
    public boolean deleteCache(String tableName, String whereClause, String whereArgs);

    /**
     * 更新
     *
     * @param tableName   更改數據的數據表
     * @param columnName  "url=?" 更改的數據的字段名
     * @param columnValue {name}; 更改的數據的字段值
     * @param object      更改的數據
     * @return
     */
    public boolean updateCache(String tableName, String columnName, String columnValue, Object object);

    /**
     *
     * @param tableName  查詢的數據庫的名字
     * @param entityType 查詢的數據庫所對應的module
     * @param fieldName  查詢的字段名
     * @param value      查詢的字段值
     * @return
     */
    public <T> ArrayList<T> queryCache(String tableName, Class<T> entityType, String fieldName, String value);

    public void clearFeedTable();
}

一些數據庫操作


ChannelDao.java

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.my_movingbricks.dbinit.db.DbManager;
import com.my_movingbricks.dbinit.db.MySQLiteOpenHelper;
import com.my_movingbricks.dbinit.dbinterface.ChannelDaoInface;

import java.lang.reflect.Field;
import java.util.ArrayList;

/**
 * TP0826 操作數據庫的封裝類
 * Created by 搬磚小能手 on 2017/4/6.
 * E-mail:40492459@qq.com.
 * Signature:當你的才華滿足不了你的野心的時候,那麼你應該靜下心來學習.
 * Alert:語言的巨人,行動的矮子!
 */
public class ChannelDao<T> implements ChannelDaoInface<T> {
    private DbManager manager;
    private SQLiteDatabase db;

    public ChannelDao() {
        //創建數據庫
        manager = DbManager.newInstances();
        db = manager.getDataBase();
    }

    /**
     * 向數據庫插入數據
     *
     * @param tableName 數據庫插入數據的數據表
     * @param item    數據庫插入的對象
     */
    @Override
    public boolean addCache(String tableName, T item) {
        boolean flag = false;
        long id = 0;
        Class clazz = item.getClass();
        Field[] fields = clazz.getDeclaredFields();//獲取該類所有的屬性
        ContentValues value = new ContentValues();
        for (Field field : fields) {
            try {
                field.setAccessible(true); //取消對age屬性的修飾符的檢查訪問,以便爲屬性賦值
                String content = (String) field.get(item);//獲取該屬性的內容
                value.put(field.getName(), content);
                field.setAccessible(false);//恢復對age屬性的修飾符的檢查訪問
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        id = db.insert(tableName, null, value);
        flag = (id != -1 ? true : false);
        return flag;
    }

    /**
     * 刪除數據
     *
     * @param tableName 刪除數據庫的表名
     * @param whereClause 刪除的字段名
     * @param whereArgs     刪除的字段的值
     */
    @Override
    public boolean deleteCache(String tableName, String whereClause, String whereArgs) {
        boolean flag = false;
        int count = 0;
        count =db.delete(tableName, whereClause + "=?", new String[]{whereArgs});
        flag = (count > 0 ? true : false);
        return flag;
    }

    /**
     * 更改數據庫內容
     *
     * @param tableName   更改數據的數據表
     * @param columnName  更改的數據的字段名
     * @param columnValue 更改的數據的字段值
     * @param object      更改的數據
     */
    @Override
    public boolean updateCache(String tableName, String columnName, String columnValue, Object object) {
        boolean flag = false;
        int count = 0;
        try {
            Class clazz = object.getClass();
            Field[] fields = clazz.getDeclaredFields();//獲取該類所有的屬性
            ContentValues value = new ContentValues();
            for (Field field : fields) {
                field.setAccessible(true); //取消對age屬性的修飾符的檢查訪問,以便爲屬性賦值
                String content = (String) field.get(object);//獲取該屬性的內容
                value.put(field.getName(), content);
                field.setAccessible(false);//恢復對age屬性的修飾符的檢查訪問
            }
            count=db.update(tableName, value, columnName + "=?", new String[]{columnValue});
            flag = (count > 0 ? true : false);
        } catch (IllegalAccessException e1) {
            e1.printStackTrace();
        }
        return flag;
    }
    /**
     *
     * @param tableName  查詢的數據庫的名字
     * @param entityType 查詢的數據庫所對應的module
     * @param fieldName  查詢的字段名
     * @param value      查詢的字段值
     * @param <T>        泛型代表AttendInformation,Customer,Order,User,WorkDaily類
     * @return 返回查詢結果,結果爲AttendInformation,Customer,Order,User,WorkDaily對象
     */
    @Override
    public <T> ArrayList<T> queryCache(String tableName, Class<T> entityType, String fieldName, String value) {

        ArrayList<T> list = new ArrayList();
        Cursor cursor = db.query(tableName, null, fieldName + " like ?", new String[]{value}, null, null, " id desc", null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {//返回遊標是否指向第最後一行的位置
            try {
                T t = entityType.newInstance();
                for (int i = 0; i < cursor.getColumnCount(); i++) {
                    String columnName = cursor.getColumnName(i);// 獲取數據記錄第i條字段名的
                    String content = cursor.getString(i);//獲得獲取的數據記錄第i條字段的內容
                    Field field = entityType.getDeclaredField(columnName);//獲取該字段名的Field對象。
                    field.setAccessible(true);//取消對age屬性的修飾符的檢查訪問,以便爲屬性賦值
                    field.set(t, content);
                    field.setAccessible(false);//恢復對age屬性的修飾符的檢查訪問
                }
                list.add(t);
                cursor.moveToNext();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

    /**
     * 刪除表中的數據
     */
    @Override
    public void clearFeedTable() {
        String sql = "DELETE FROM " + MySQLiteOpenHelper.CREATE_CUSTOMER + ";";
        db.execSQL(sql);
        revertSeq();
    }


    /**
     * 以SQLHelper.TABLE_CHANNEL表作爲條件,新建表sqlite_sequence,當name=表名的時候
     * 更新seq=0;
     */
    private void revertSeq() {
        String sql = "update sqlite_sequence set seq=0 where name='"
                + MySQLiteOpenHelper.CREATE_CUSTOMER + "'";
        db.execSQL(sql);
    }


    //關閉數據庫
    private void OnCliar(ContentValues value) {
        value.clear();
    }
}

操作的實現


TableOperate.java


import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.my_movingbricks.dbinit.db.DbManager;

/**
 * abc
 * Created by 搬磚小能手 on 27/10/2017.
 * E-mail:[email protected].
 * Signature:當你的才華滿足不了你的野心的時候,那麼你應該靜下心來學習.
 * Alert:語言的巨人,行動的矮子!
 */
public class TableOperate {
    private DbManager manager;
    private SQLiteDatabase db;

    public TableOperate() {
        //創建數據庫
        manager = DbManager.newInstances();
        db = manager.getDataBase();
    }

    /**
     * 添加數據
     */
    public void insertData(String tableName, ContentValues values) {
        db.insert(tableName, null, values);// 插入一條數據
    }

    public ContentValues initContentValues(String[] key, String[] values) {
        if (key.length != values.length) return null;
        ContentValues cv = new ContentValues();
        for (int i = 0; i < key.length; i++) {
            cv.put(key[i], values[i]);
        }
        return cv;
    }

    public void insertData(String tableName, String[] key, String[] values) {
        db.insert(tableName, null, initContentValues(key, values));// 插入一條數據
    }

    /**
     * 更新數據
     *
     * @param values
     * @param whereClause "url=?"
     * @param whereArgs   {name};
     */
    public void updateData(String tableName, ContentValues values, String whereClause, String[] whereArgs) {
        db.update(tableName, values, whereClause,
                whereArgs);
    }

    public void updateData(String tableName, String[] key, String[] values, String whereClause, String[] whereArgs) {
        db.update(tableName, initContentValues(key, values), whereClause, whereArgs);
    }

    /**
     * 刪除數據
     *
     * @param whereClause "url=?"
     * @param whereArgs   {name};
     */
    public void deleteData(String tableName, String whereClause, String[] whereArgs) {
        db.delete(tableName, whereClause, whereArgs);
    }

    /**
     * 查詢數據
     *
     * @param tableName     表名,不能爲null
     * @param columns       要查詢的列名,可以是多個,可以爲null,表示查詢所有列
     * @param selection     查詢條件,比如id=? and name=? 可以爲null
     * @param selectionArgs 對查詢條件賦值,一個問號對應一個值,按順序 可以爲null
     * @param groupBy
     * @param having        語法have,可以爲null
     * @param orderBy       語法,按xx排序,可以爲null
     * @return
     */

    public Cursor selectData(String tableName, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
        Cursor cursor = db.query(tableName, columns, selection, selectionArgs, groupBy, having, orderBy);
        return cursor;
    }

    public void selectData(Cursor cursor, String... key) {
        if (cursor.moveToFirst()) { // 返回假時 那就爲空   移動光標到第一行
            do {
                for (int i = 0; i < key.length; i++) {
                    String name=cursor.getString(cursor.getColumnIndex(key[i]));
                }
            } while (cursor.moveToNext());
        }
        cursor.close();
    }
    /**
     if (cursor.moveToFirst()) {// 返回假時 那就爲空   移動光標到第一行
     do {
     // 遍歷cursor對象,取出數據 對比搜索到的數據,如果有則爲已收藏收藏
     String url = cursor.getString(cursor.getColumnIndex("url"));
     String theme = cursor.getString(cursor.getColumnIndex("theme"));
     String content = cursor.getString(cursor
     .getColumnIndex("content"));
     }
     } while (cursor.moveToNext());
     */
}

另一個實現類,以便滿足多種需求

好了 就這麼愉快的分享完了,總體來說比較簡單,當然大家可以去使用目前比較成熟的框架greenDAO或者是xutlis的db模塊,也是比較通俗易懂的,這裏就不做介紹了哈, 如果文章有錯誤希望小夥伴們告知一下哈 。

文章末尾附上設計的幾個類的下載地址:點擊傳送

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章