android Sqlite的簡單封裝和使用
阿新 • • 發佈:2019-02-02
SQLiteOpenHelper的建立
如果想通過類繼承了SQLiteOpenHelper,然後一次建立多個表,是不能在其它類中連續呼叫建立表的,第二張表是不能夠被建立的,必須要在Helper的類中建立,就是在onCreate時建立表。
以下程式碼抽取程式中的部分程式碼,僅供參考,本人還在學習中,雖然網上已經有很多成熟的框架可以使用,但還是想研究一下,希望高手指教,不喜勿噴!
Helper類的建立,主要用於生成資料庫和表。
package com.cdl.mydb.db; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; /** * 建立多表資料庫 */ public class MultiTableHelper extends SQLiteOpenHelper { private final String TAG = "MultiTableHelper"; private String[] tableNames; private String[] sqls; /** * 初始化建構函式 * * @param context * @param name 資料庫名 * @param factory 遊標工廠(基本不用) * @param version 版本號 */ public MultiTableHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } /** * 初始化建構函式 * * @param context * @param dbName 資料庫名 * @param version 版本號 * @param tableNames 表名 * @param sqls SQL語句 */ public MultiTableHelper(Context context, String dbName, int version, String[] tableNames, String[] sqls) { this(context, dbName, null, version); this.tableNames = tableNames; this.sqls = sqls; } // 當呼叫SQLiteDatabase中的getWritableDatabase()函式的時候會檢測表是否存在,如果不存在onCreate將被呼叫建立表,否則將不會在被呼叫。 @Override public void onCreate(SQLiteDatabase db) { if (db != null) { for (int i = 0; i < tableNames.length; i++) { Log.d(TAG, "tableName =" + tableNames[i]); Log.d(TAG, "sql=" + sqls[i]); db.execSQL("create table if not exists " + tableNames[i] + sqls[i]); } } } // 版本更新 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.d(TAG, "oldVersion=" + oldVersion); Log.d(TAG, "newVersion=" + newVersion); if (db != null) { // 如果表存在就刪除 for (int i = 0; i < tableNames.length; i++) { db.execSQL("drop table if exists" + tableNames[i]); } // 重新初始化 onCreate(db); } } }
管理類的建立,主要用於實現資料庫的增刪改查和一些常用的操作的封裝方法
package com.cdl.mydb.DBManager import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; /** * 資料庫管理類 * Created by chen on 2016/11/29. */ public class DBManager { private final String TAG = "DBManager"; private Context context; private SQLiteDatabase mSQLiteDatabase; private SQLiteOpenHelper mSQLiteOpenHelper; private Cursor mCursor; private StringBuffer mSqlBuffer; private boolean isSqlSuccessed = false; public DBManager(Context context) { super(); this.context = context; mSqlBuffer = new StringBuffer(); } /** * 建立多表資料庫 * * @param dbName 資料庫名稱 * @param version 資料庫版本 * @param tableNames 資料庫表名 * @param sqls sql語句 */ public void create(String dbName, int version, String[] tableNames, String[] sqls) { if (isSqlSuccessed || sqls.length > 0) { for (int i = 0; i < sqls.length; i++) { if (!isLegalSql(sqls[i])) { Log.e(TAG, "Sql語句不合法"); } } if (mSQLiteOpenHelper == null) { mSQLiteOpenHelper = new MultiTableHelper(context, dbName, version, tableNames, sqls); } } else { Log.e(TAG, "Sql語句不合法"); } } /** * 建立單表資料庫 * * @param dbName 資料庫名稱 * @param version 資料庫版本 * @param tableName 資料庫表名 * @param sql sql語句 */ public void create(String dbName, int version, String tableName, String sql) { if (isSqlSuccessed || isLegalSql(sql)) { mSQLiteOpenHelper = new SingleTableHelper(context, dbName, version, tableName, sql); } else { Log.e(TAG, "Sql語句不合法"); } } /** * 是否為合法Sql語句 */ private boolean isLegalSql(String sql) { if (sql != null && sql.length() > 1) { if ("(".equals(sql.charAt(0) + "") && ")".equals(sql.charAt(sql.length() - 1) + "")) { return true; } } return false; } /** * 新增主鍵 */ public DBManager addPrimaryKey() { mSqlBuffer.append("_id integer primary key autoincrement,"); return this; } /** * 建立TEXT型欄位 * * @param key 欄位名 */ public DBManager addText(String key) { mSqlBuffer.append(key + " text,"); return this; } /** * 建立BLOB型欄位 * * @param key 欄位名 */ public DBManager addBlob(String key) { mSqlBuffer.append(key + " blob,"); return this; } /** * 建立INTEGER型欄位 * * @param key 欄位名 */ public DBManager addInteger(String key) { mSqlBuffer.append(key + " integer,"); return this; } /** * 獲取SQL語句 */ public String getSql() { String sql = null; if (mSqlBuffer.length() > 0) { sql = mSqlBuffer.toString(); sql = sql.substring(0, sql.length() - 1); sql = "(" + sql + ")"; Log.i(TAG, "getSql: " + sql); mSqlBuffer = new StringBuffer(); isSqlSuccessed = true; } return sql; } /** * 執行一條sql語句 * * @param sql */ public void mExecSQL(String sql) { mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase(); mSQLiteDatabase.execSQL(sql); closeAll(); } /** * 增加資料 * * @param tableName 表名 * @param nullColumnHack 非空欄位名 * @param values 資料來源 */ public void mInsert(String tableName, String nullColumnHack, ContentValues values) { mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase(); mSQLiteDatabase.insert(tableName, nullColumnHack, values); closeAll(); } /** * 刪除資料 * * @param tableName 表名 * @param whereClause (eg:"_id=?") * @param whereArgs (eg:new String[] { "01" } ) */ public void mDelete(String tableName, String whereClause, String[] whereArgs) { mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase(); mSQLiteDatabase.delete(tableName, whereClause, whereArgs); closeAll(); } /** * 更新 * * @param tableName * @param values * @param whereClause * @param whereArgs */ public void mUpdate(String tableName, ContentValues values, String whereClause, String[] whereArgs) { mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase(); mSQLiteDatabase.update(tableName, values, whereClause, whereArgs); closeAll(); } /** * 更新 * * @param tableName 表名 * @param values 更新的資料 * @param whereClause 更新的條件(eg:_id = 01) */ public void mUpdate(String tableName, ContentValues values, String whereClause) { mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase(); mSQLiteDatabase.update(tableName, values, whereClause, null); closeAll(); } /** * 查詢 * * @param tableName * @param columns * @param selection * @param selectionArgs * @param groupBy * @param having * @param orderBy * @return mCursor 遊標 */ public Cursor mQuery(String tableName, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) { mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase(); mCursor = mSQLiteDatabase.query(tableName, columns, selection, selectionArgs, groupBy, having, orderBy); return mCursor; } /** * 查詢全部(查詢後需要在呼叫的類中手動呼叫closeAll()方法來關閉全部函式) * * @param tableName 表名 * @param orderBy 排序方式(asc升序,desc降序) * @return mCursor 遊標 */ public Cursor mQueryAll(String tableName, String orderBy) { mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase(); mCursor = mSQLiteDatabase.query(tableName, null, null, null, null, null, orderBy); return mCursor; } /** * 從資料庫中刪除表 * * @param tableName 表名 */ public void mDropTable(String tableName) { mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase(); mSQLiteDatabase.execSQL("drop table if exists " + tableName); Log.e(TAG, "已刪除" + tableName + "表"); closeAll(); } /** * 刪除表中的全部資料 * * @param tableName 表名 */ public void mDeleteTable(String tableName) { mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase(); mSQLiteDatabase.execSQL("delete from " + tableName); Log.e(TAG, "已清空" + tableName + "表"); closeAll(); } /** * 判斷某張表是否存在 * * @param tableName 表名 * @return true 存在 */ public boolean isTableExist(String tableName) { boolean result = false; if (tableName == null) { return false; } try { mSQLiteDatabase = mSQLiteOpenHelper.getReadableDatabase(); String sql = "select count(*) as c from sqlite_master where type ='table' and name ='" + tableName.trim() + "' "; mCursor = mSQLiteDatabase.rawQuery(sql, null); if (mCursor.moveToNext()) { int count = mCursor.getInt(0); if (count > 0) { result = true; } } } catch (Exception e) { Log.e(TAG, tableName + "表不存在"); } closeAll(); return result; } /** * 獲取表中有多少條資料 * * @param tableName * @return */ public int getDataNum(String tableName) { mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase(); mCursor = mSQLiteDatabase.query(tableName, null, null, null, null, null, null); int num = mCursor.getCount(); closeAll(); return num; } /** * 資料庫是否存在要查詢的這條資料 * * @param tableName 表名 * @param columnName 需要查詢欄位 * @param data 需要查詢資料 * @return */ public boolean hasThisData(String tableName, String columnName, String data) { boolean result = false; mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase(); mCursor = mSQLiteDatabase.query(tableName, null, null, null, null, null, null); while (mCursor.moveToNext()) { String columnValues = mCursor.getString(mCursor.getColumnIndex(columnName)); // 有這條資料 if (data.equals(columnValues)) { result = true; break; } } closeAll(); return result; } /** * 關閉全部 */ public void closeAll() { if (mCursor != null && !mCursor.isClosed()) { mCursor.close(); } else { Log.e(TAG, "closeAll: mCursor已關閉"); } if (mSQLiteOpenHelper != null) { mSQLiteOpenHelper.close(); } else { Log.e(TAG, "closeAll: mSQLiteOpenHelper已關閉"); } if (mSQLiteDatabase != null && mSQLiteDatabase.isOpen()) { mSQLiteDatabase.close(); } else { Log.e(TAG, "closeAll: mSQLiteDatabase已關閉"); } } }
實現類的建立,主要用於根據不同的資料庫真正的實現對錶資料的增刪改查和一些複雜方法的封裝
package com.shkefu.sichouelu.db; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.util.Log; import com.shkefu.sichouelu.bean.GridViewInfo; import java.util.ArrayList; /** * GridView資料庫 */ public class GridViewDB { private final String TAG = "GridViewDB"; public static final String TABLE_HOME_PAGE = "home_page_table"; public static final String TABLE_MY_PAGE = "my_page_table"; private String dbName = "GridView.db";// 資料庫名 private String tableName;// 表名 private int version = 1;// 版本號 private DBManager mDBManager; private ArrayList<GridViewInfo> localDataInfos = new ArrayList<GridViewInfo>(); public GridViewDB(Context context, String tableName) { mDBManager = new DBManager(context); String sql = mDBManager.addPrimaryKey().addText("menu_id").addText("menu_logo").addText("menu_url").addText("grid_index").addText("more").getSql(); String[] tables = {TABLE_HOME_PAGE, TABLE_MY_PAGE}; String[] slqs = {sql, sql}; mDBManager.create(dbName, version, tables, slqs); this.tableName = tableName; } public static GridViewDB init(Context context, String tableName) { return new GridViewDB(context, tableName); } /** * 增加新資料 * * @param contentValues 資料來源 */ public void addData(ContentValues contentValues) { mDBManager.mInsert(tableName, "menu_id", contentValues); Log.i(TAG, "delData:增加了一條資料 "); } /** * 刪除一條資料 * * @param menu_id */ public void delData(String menu_id) { mDBManager.mDelete(tableName, "menu_id=?", new String[]{menu_id}); Log.i(TAG, "delData:刪除了一條資料 "); } /** * 清空表中的內容 */ public void delTable() { mDBManager.mDeleteTable(tableName); } /** * 是否是空表 * * @return true 是空表 */ public boolean isEmptyTable() { if (mDBManager.getDataNum(tableName) > 0) { return false; } return true; } /** * 資料庫是否存在要查詢的這條資料 * * @param columnName 查詢的欄位 * @param data 查詢的資料 * @return */ public boolean hasThisData(String columnName, String data) { return mDBManager.hasThisData(tableName, columnName, data); } /** * 本地資料庫是否存在這條MenuID * * @param data 查詢的資料 * @return true 有這條資料 */ public boolean hasThisMenuID(String data) { return mDBManager.hasThisData(tableName, "menu_id", data); } /** * 修改一條資料的內容 * * @param values 資料 * @param whereclause 條件 */ public void modifyData(ContentValues values, String whereclause) { mDBManager.mUpdate(tableName, values, whereclause); Log.i(TAG, "modifyData: 修改了一條資料"); } /** * 查詢本地資料庫的全部資料 * * @return */ public ArrayList<GridViewInfo> findAllData() { localDataInfos.clear(); Cursor cursor = mDBManager.mQueryAll(tableName, "menu_id asc"); while (cursor.moveToNext()) { String menu_id = cursor.getString(cursor.getColumnIndex("menu_id")); String menu_logo = cursor.getString(cursor.getColumnIndex("menu_logo")); String menu_url = cursor.getString(cursor.getColumnIndex("menu_url")); GridViewInfo gridViewInfo = new GridViewInfo(); gridViewInfo.setMenu_id(menu_id); gridViewInfo.setMenu_logo(menu_logo); gridViewInfo.setMenu_url(menu_url); localDataInfos.add(gridViewInfo); } mDBManager.closeAll(); return localDataInfos; } }
最後對資料來源做操作時,這個類已經脫離了對資料庫基礎方法的使用,只需要對我們平時使用的常用方法做邏輯處理就可以了,不在需要考慮針對資料庫做其它判斷了。這樣在編寫程式碼時提高了程式碼的複用性和邏輯結構清晰性。以下程式碼只是對伺服器返回的一個監聽處理,並不是一個完整的類,最後通過對資料來源的處理,實現了與伺服器資料與本地資料的同步。
private Listener<String> listener = new Listener<String>() {
@Override
public void onResponse(String response) {
Log.i(TAG, "gridview response = " + response);
try {
homepageInfos.clear();
mypageInfos.clear();
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.has("mobileState")) {
String mobileState = jsonObject.getString("mobileState");
switch (mobileState) {
case "0":// 成功
//建立資料庫和表
homepageDb = new GridViewDB(context, GridViewDB.TABLE_HOME_PAGE);
JSONArray homepageArray = jsonObject.getJSONArray("Homepagelist");
//如果伺服器沒有返回資料
if (homepageArray.length() <= 0) {
Log.e(TAG, "首頁列表沒有返回資料");
//清空表
homepageDb.delTable();
} else {
for (int i = 0; i < homepageArray.length(); i++) {
GridViewInfo gridViewInfo = new GridViewInfo();
JSONObject mJsonObject = homepageArray.getJSONObject(i);
Log.i(TAG, "mJsonObject =" + mJsonObject.toString());
if (mJsonObject.has("menu_logo")) {
menu_logo = mJsonObject.getString("menu_logo");
gridViewInfo.setMenu_logo(menu_logo);
}
if (mJsonObject.has("menu_url")) {
menu_url = mJsonObject.getString("menu_url");
gridViewInfo.setMenu_url(menu_url);
}
if (mJsonObject.has("menu_id")) {
menu_id = mJsonObject.getString("menu_id");
//補位
if (menu_id.length() == 1) {
menu_id = "0" + menu_id;
}
gridViewInfo.setMenu_id(menu_id);
}
homepageInfos.add(gridViewInfo);
}
if (homepageInfos.size() > 0) {
Log.v(TAG, "首頁列表有返回資料");
//本地沒有資料
if (homepageDb.isEmptyTable()) {
for (int i = 0; i < homepageInfos.size(); i++) {
menu_logo = homepageInfos.get(i).getMenu_logo();
menu_url = homepageInfos.get(i).getMenu_url();
menu_id = homepageInfos.get(i).getMenu_id();
mValues = new ContentValues();
mValues.clear();
mValues.put("menu_id", menu_id);
mValues.put("menu_logo", menu_logo);
mValues.put("menu_url", menu_url);
//新增新資料
homepageDb.addData(mValues);
}
} else {
//本地資料庫有資料
for (int i = 0; i < homepageInfos.size(); i++) {
menu_id = homepageInfos.get(i).getMenu_id();
menu_logo = homepageInfos.get(i).getMenu_logo();
menu_url = homepageInfos.get(i).getMenu_url();
mValues = new ContentValues();
mValues.clear();
mValues.put("menu_id", menu_id);
mValues.put("menu_logo", menu_logo);
mValues.put("menu_url", menu_url);
//本地資料庫有本條資料
if (homepageDb.hasThisMenuID(menu_id)) {
//更新資料
homepageDb.modifyData(mValues, "menu_id = " + menu_id);
} else {
//新增新資料
homepageDb.addData(mValues);
}
}
localDataInfos.clear();
localDataInfos = homepageDb.findAllData();
boolean result = false;
for (int i = 0; i < localDataInfos.size(); i++) {
String menu_id_local = localDataInfos.get(i).getMenu_id();
Log.v(TAG, "menu_id_local=" + menu_id_local);
for (int j = 0; j < homepageInfos.size(); j++) {
String menu_id_homepage = homepageInfos.get(j).getMenu_id();
Log.v(TAG, "menu_id_homepage=" + menu_id_homepage);
//本地資料庫是否有伺服器上的這條資料
if (menu_id_local.equals(menu_id_homepage)) {
result = true;
break;
}
}
//本地資料庫沒有伺服器上的這條資料
if (!result) {
//刪除本地資料庫中的這條資料
homepageDb.delData(menu_id_local);
}
result = false;
}
}
}
}
mypageDb = new GridViewDB(context, GridViewDB.TABLE_MY_PAGE);
JSONArray mypageArray = jsonObject.getJSONArray("Mypagelist");
//如果伺服器沒有返回資料
if (mypageArray.length() <= 0) {
Log.e(TAG, "我的列表沒有返回資料");
//清空表
mypageDb.delTable();
} else {
for (int i = 0; i < mypageArray.length(); i++) {
GridViewInfo gridViewInfo = new GridViewInfo();
JSONObject mJsonObject = mypageArray.getJSONObject(i);
Log.i(TAG, "mJsonObject =" + mJsonObject.toString());
if (mJsonObject.has("menu_logo")) {
String menu_logo = mJsonObject.getString("menu_logo");
gridViewInfo.setMenu_logo(menu_logo);
}
if (mJsonObject.has("menu_url")) {
String menu_url = mJsonObject.getString("menu_url");
gridViewInfo.setMenu_url(menu_url);
}
if (mJsonObject.has("menu_id")) {
String menu_id = mJsonObject.getString("menu_id");
//補位
if (menu_id.length() == 1) {
menu_id = "0" + menu_id;
}
gridViewInfo.setMenu_id(menu_id);
}
mypageInfos.add(gridViewInfo);
}
if (mypageInfos.size() > 0) {
Log.v(TAG, "我的列表有返回資料");
//本地沒有資料
if (mypageDb.isEmptyTable()) {
for (int i = 0; i < mypageInfos.size(); i++) {
menu_logo = mypageInfos.get(i).getMenu_logo();
menu_url = mypageInfos.get(i).getMenu_url();
menu_id = mypageInfos.get(i).getMenu_id();
mValues = new ContentValues();
mValues.clear();
mValues.put("menu_id", menu_id);
mValues.put("menu_logo", menu_logo);
mValues.put("menu_url", menu_url);
//新增新資料
mypageDb.addData(mValues);
}
} else {
//本地資料庫有資料
for (int i = 0; i < mypageInfos.size(); i++) {
menu_id = mypageInfos.get(i).getMenu_id();
menu_logo = mypageInfos.get(i).getMenu_logo();
menu_url = mypageInfos.get(i).getMenu_url();
mValues = new ContentValues();
mValues.clear();
mValues.put("menu_id", menu_id);
mValues.put("menu_logo", menu_logo);
mValues.put("menu_url", menu_url);
//本地資料庫有本條資料
if (mypageDb.hasThisMenuID(menu_id)) {
//更新資料
mypageDb.modifyData(mValues, "menu_id = " + menu_id);
} else {
//新增新資料
mypageDb.addData(mValues);
}
}
localDataInfos.clear();
localDataInfos = mypageDb.findAllData();
boolean result = false;
for (int i = 0; i < localDataInfos.size(); i++) {
String menu_id_local = localDataInfos.get(i).getMenu_id();
Log.v(TAG, "menu_id_local=" + menu_id_local);
for (int j = 0; j < mypageInfos.size(); j++) {
String menu_id_homepage = mypageInfos.get(j).getMenu_id();
Log.v(TAG, "menu_id_homepage=" + menu_id_homepage);
//本地資料庫是否有伺服器上的這條資料
if (menu_id_local.equals(menu_id_homepage)) {
result = true;
break;
}
}
//本地資料庫沒有伺服器上的這條資料
if (!result) {
//刪除本地資料庫中的這條資料
mypageDb.delData(menu_id_local);
}
result = false;
}
}
}
}
break;
default:
Log.e(TAG, "mobileState =" + mobileState);
break;
}
}
} catch (JSONException e) {
e.printStackTrace();
UIUtils.showToast(context, StatusCode.JSON_EXCEPTION);
}
}
};