開發Android的同窗都知道sdk已經爲咱們提供了一個SQLiteOpenHelper類來建立和管理SQLite數據庫,經過寫一個子類去繼承它,就能夠方便的建立、管理數據庫。可是當咱們須要去作增刪改查的操做的時候,就得經過getWritableDatabase獲取一個SQLiteDataBase而後老老實實去寫操做值的put以及查詢返回的Cursor處理,其實咱們能夠搞一個對象來幫咱們幹這些事情,打造屬於你本身的數據庫操做類。java
假設如今咱們什麼都沒有,咱們要去搞一個對象來給咱們幹這件事情,它須要有什麼才能夠幹呢?
先想一想要作的事情:管理數據庫的操做
那要作數據庫的操做須要什麼就很簡單了吧?
一、要操做數據庫,因此須要一個SQLiteDataBase對象,能夠經過SQLiteOpenHelper的子類來獲取。
二、此外數據庫要建立,還須要數據庫信息吧?那就直接變量引入。
三、有了數據庫信息,建立了數據庫,你要操做,怎麼也得告訴我操做哪一個表。因此還得包含建立表和更新表的信息,因爲表通常會有多張,因此這裏用一個數組變量。sql
有了信息還得交互,否則我怎麼知道你要怎麼建立表,因此咱們在構造方法中直接獲取這些信息。數據庫
接下看上面文字的代碼表示數組
public abstract class DataBaseHelper { /** * 用來建立和獲取數據庫的SQLiteOpenHelper */ protected DBHelper mDbHelper; /** * 數據庫對象 */ protected SQLiteDatabase mDb; /** * 數據庫信息 */ private int mDbVersion;//版本 private String mDbName;//數據庫名 /** * 建立表語句 */ private String[] mDbCreateSql; /** * 更新表語句 */ private String[] mDbUpdateSql; protected abstract int getMDbVersion(Context context); protected abstract String getDbName(Context context); protected abstract String[] getDbCreateSql(Context context); protected abstract String[] getDbUpdateSql(Context context); public DataBaseHelper(Context context) { this.mDbVersion = this.getMDbVersion(context); this.mDbName = this.getDbName(context); this.mDbCreateSql = this.getDbCreateSql(context); this.mDbUpdateSql = this.getDbUpdateSql(context); this.mDbHelper = new DBHelper(context,this.mDbName,null,this.mDbVersion); } protected void open(){ new Thread(new Runnable() { @Override public void run() { mDb = mDbHelper.getWritableDatabase(); } }).start(); } protected SQLiteDatabase getDB(){ return this.mDb; } public void close(){ this.mDb.close(); this.mDbHelper.close(); } private class DBHelper extends SQLiteOpenHelper{ public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase db) { String[] arr = DataBaseHelper.this.mDbCreateSql; //執行建立表語句 for (int i=0;i<arr.length;i++){ String sql = arr[i]; db.execSQL(sql); } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { String[] arr = DataBaseHelper.this.mDbUpdateSql; //執行更新語句 for (int i=0;i<arr.length;i++){ String sql = arr[i]; db.execSQL(sql); } } } }
代碼比較簡單,包含了進行數據庫操做要用到的各類信息,而且在初始化的進行了賦值。同時還提供了SQLiteDatabase的open、close。同時在這裏用到了抽象方法是由於考慮建立多個數據庫的狀況,讓子類來提供具體的數據庫信息,我只管作建立和操做就好了。app
這裏咱們的數據庫操做類已經初顯雛形了,可是如今除了建立表還沒什麼用。操做類不提供簡便的操做還叫什麼操做類,下面就來講說操做。ide
咱們要作操做類,無非是要簡化操做,就像當老闆同樣。我告訴你一些用到的東西,你去給我完成這個事情。哈哈。this
假如我如今就是要操做數據庫的老闆,那我其實只想告訴你必要的事情,其它的我都不想作。.net
那麼必要的信息只有表名,要操做的字段和值,若是是刪除、更新、和查詢的話多加個篩選條件。接下來看代碼code
/** * 統一對ContentValues處理 * @param contentValues * @param key * @param value */ private void ContentValuesPut(ContentValues contentValues,String key,Object value){ if (value==null){ contentValues.put(key,""); }else{ String className = value.getClass().getName(); if (className.equals("java.lang.String")){ contentValues.put(key,value.toString()); } else if (className.equals("java.lang.Integer")){ contentValues.put(key,Integer.valueOf(value.toString())); } else if (className.equals("java.lang.Float")){ contentValues.put(key,Float.valueOf(value.toString())); } else if (className.equals("java.lang.Double")){ contentValues.put(key,Double.valueOf(value.toString())); } else if (className.equals("java.lang.Boolean")){ contentValues.put(key,Boolean.valueOf(value.toString())); } else if (className.equals("java.lang.Long")){ contentValues.put(key,Long.valueOf(value.toString())); } else if (className.equals("java.lang.Short")){ contentValues.put(key,Short.valueOf(value.toString())); } } } /** * 根據數組的列和值進行insert * @param tableName * @param columns * @param values * @return */ public boolean insert(String tableName,String[] columns,Object[] values){ ContentValues contentValues = new ContentValues(); for (int rows = 0; rows < columns.length;++rows){ ContentValuesPut(contentValues,columns[rows],values[rows]); } long rowId = this.mDb.insert(tableName,null,contentValues); return rowId!=-1; } /** * 根據map來進行insert * @param tableName * @param columnValues * @return */ public boolean insert(String tableName,Map<String,Object> columnValues){ ContentValues contentValues = new ContentValues(); Iterator iterator = columnValues.keySet().iterator(); while (iterator.hasNext()){ String key = (String) iterator.next(); this.ContentValuesPut(contentValues,key,columnValues.get(key)); } long rowId = this.mDb.insert(tableName,null,contentValues); return rowId!=-1; } /** * 統一對數組where條件進行拼接 * @param whereColumns * @return */ private String initWhereSqlFromArray(String[] whereColumns){ StringBuffer whereStr = new StringBuffer(); for (int i=0;i<whereColumns.length;++i){ whereStr.append(whereColumns[i]).append(" = ? "); if (i<whereColumns.length-1){ whereStr.append(" and "); } } return whereStr.toString(); } /** * 統一對map的where條件和值進行處理 * @param whereParams * @return */ private Map<String,Object> initWhereSqlFromMap(Map<String,String> whereParams){ Set set = whereParams.keySet(); String[] temp = new String[whereParams.size()]; int i = 0; Iterator iterator = set.iterator(); StringBuffer whereStr = new StringBuffer(); while (iterator.hasNext()){ String key = (String) iterator.next(); whereStr.append(key).append(" = ? "); temp[i] = whereParams.get(key); if (i<set.size()-1){ whereStr.append(" and "); } i++; } HashMap result = new HashMap(); result.put("whereSql",whereStr); result.put("whereSqlParam",temp); return result; } /** * 根據數組條件來update * @param tableName * @param columns * @param values * @param whereColumns * @param whereArgs * @return */ public boolean update(String tableName,String[] columns,Object[] values,String[] whereColumns,String[] whereArgs){ ContentValues contentValues = new ContentValues(); for (int i=0;i<columns.length;++i){ this.ContentValuesPut(contentValues,columns[i],values[i]); } String whereClause = this.initWhereSqlFromArray(whereColumns); int rowNumber = this.mDb.update(tableName,contentValues,whereClause,whereArgs); return rowNumber > 0 ; } /** * 根據map值來進行update * @param tableName * @param columnValues * @param whereParam * @return */ public boolean update(String tableName,Map<String,Object> columnValues,Map<String,String> whereParam){ ContentValues contentValues = new ContentValues(); Iterator iterator = columnValues.keySet().iterator(); String columns; while (iterator.hasNext()){ columns = (String) iterator.next(); ContentValuesPut(contentValues,columns,columnValues.get(columns)); } Map map = this.initWhereSqlFromMap(whereParam); int rowNumber = this.mDb.update(tableName,contentValues,(String)map.get("whereSql"),(String[]) map.get("whereSqlParam")); return rowNumber > 0; } /** * 根據數組條件進行delete * @param tableName * @param whereColumns * @param whereParam * @return */ public boolean delete(String tableName,String[] whereColumns,String[] whereParam){ String whereStr = this.initWhereSqlFromArray(whereColumns); int rowNumber = this.mDb.delete(tableName,whereStr,whereParam); return rowNumber > 0; } /** * 根據map來進行delete * @param tableName * @param whereParams * @return */ public boolean delete(String tableName,Map<String,String> whereParams){ Map map = this.initWhereSqlFromMap(whereParams); int rowNumber = this.mDb.delete(tableName,map.get("whereSql").toString(),(String[]) map.get("whereSqlParam")); return rowNumber > 0; } /** * 查詢返回List * @param sql * @param params * @return */ public List<Map> queryListMap(String sql,String[] params){ ArrayList list = new ArrayList(); Cursor cursor = this.mDb.rawQuery(sql,params); int columnCount = cursor.getColumnCount(); while (cursor.moveToNext()){ HashMap item = new HashMap(); for (int i=0;i<columnCount;++i){ int type = cursor.getType(i); switch (type){ case 0: item.put(cursor.getColumnName(i),null); break; case 1: item.put(cursor.getColumnName(i), cursor.getInt(i)); break; case 2: item.put(cursor.getColumnName(i),cursor.getFloat(i)); break; case 3: item.put(cursor.getColumnName(i),cursor.getString(i)); break; } } list.add(item); } cursor.close(); return list; } /** * 查詢單條數據返回map * @param sql * @param params * @return */ public Map queryItemMap(String sql,String[] params){ Cursor cursor = this.mDb.rawQuery(sql,params); HashMap map = new HashMap(); if (cursor.moveToNext()){ for (int i = 0;i < cursor.getColumnCount();++i){ int type = cursor.getType(i); switch (type){ case 0: map.put(cursor.getColumnName(i),null); break; case 1: map.put(cursor.getColumnName(i),cursor.getInt(i)); break; case 2: map.put(cursor.getColumnName(i),cursor.getFloat(i)); break; case 3: map.put(cursor.getColumnName(i),cursor.getString(i)); break; } } } cursor.close(); return map; } public void execSQL(String sql){ this.mDb.execSQL(sql); } public void execSQL(String sql,Object[] params){ this.mDb.execSQL(sql,params); }
上面的操做代碼就完畢了,這裏主要對增刪改的參數是數組和Map的狀況進行了處理,對查詢的結果進行了處理,代碼比較簡單也都有註釋,這裏就不作特別說明了。到這裏一個數據庫操做類就成型了。xml
經過上面的過程已經可使用了,那麼先來看看使用,咱們只須要繼承操做抽象類告訴它具體的數據庫信息以及建表語句。
public class TestDBHelper extends DataBaseHelper { private static TestDBHelper mTestDBHelper; private TestDBHelper(Context context){ super(context); } public static TestDBHelper getInstance(Context context){ if (mTestDBHelper==null){ synchronized (DataBaseHelper.class){ if (mTestDBHelper==null){ mTestDBHelper = new TestDBHelper(context); if (mTestDBHelper.getDB()==null||!mTestDBHelper.getDB().isOpen()){ mTestDBHelper.open(); } } } } return mTestDBHelper; } @Override protected int getMDbVersion(Context context) { return 1; } @Override protected String getDbName(Context context) { return "test.db"; } @Override protected String[] getDbCreateSql(Context context) { String[] a = new String[1]; a[0] = "CREATE TABLE user (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,gender TEXT,age INTEGER)"; return a; } @Override protected String[] getDbUpdateSql(Context context) { return new String[0]; } }
重寫父類的抽象方法告訴它數據庫信息以及建表語句,而後提供一個單例供外部獲取,若是沒有open就open數據庫,接下來看看使用
直接獲取,而後傳入你想操做的表信息,So Easy!
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button selectBtn; private Button insertBtn; private Button updateBtn; private Button deleteBtn; private TextView contentTv; private TestDBHelper testDBHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); testDBHelper = TestDBHelper.getInstance(getApplicationContext()); selectBtn = (Button) findViewById(R.id.select_btn); insertBtn = (Button) findViewById(R.id.insert_btn); updateBtn = (Button) findViewById(R.id.update_btn); deleteBtn = (Button) findViewById(R.id.delete_bt); contentTv = (TextView) findViewById(R.id.content_tv); selectBtn.setOnClickListener(this); insertBtn.setOnClickListener(this); updateBtn.setOnClickListener(this); deleteBtn.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.select_btn: List<Map> list = testDBHelper.queryListMap("select * from user",null); contentTv.setText(String.valueOf(list)); break; case R.id.insert_btn: testDBHelper.insert("user",new String[]{"name","gender","age"},new Object[]{"qiangyu","male",23}); break; case R.id.update_btn: testDBHelper.update("user",new String[]{"name","gender","age"},new Object[]{"yangqiangyu","male",24}, new String[]{"name"},new String[]{"qiangyu"}); break; case R.id.delete_bt: testDBHelper.delete("user", new String[]{"name"},new String[]{"qiangyu"}); break; } } }
很簡單了,附一張演示圖
gif製做了作了壓縮,圖的效果很差請見諒
是否是簡單多了
yissan的博客,未經容許嚴禁轉載 http://blog.csdn.net/yissan
在第3步裏,咱們的數據庫信息,和建表語句都是寫在具體的代碼裏的,這樣咱們每次修改都要動代碼。Android推薦咱們這些具體的信息都寫在配置文件xml裏面,那麼咱們就來作一下修改。
創建一個db.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <array name="DATABASE_INFO"> <item>test.db</item> <item>1</item> </array> <array name="CREATE_TABLE_SQL"> <item>CREATE TABLE user (id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,gender TEXT,age INTEGER)</item> </array> <array name="UPDATE_TABLE_SQL"> <item></item> </array> </resources>
如今的獲取數據信息的代碼是這樣
@Override protected int getMDbVersion(Context context) { return Integer.valueOf(context.getResources().getStringArray(R.array.DATABASE_INFO)[1]); } @Override protected String getDbName(Context context) { return context.getResources().getStringArray(R.array.DATABASE_INFO)[0]; } @Override protected String[] getDbCreateSql(Context context) { return context.getResources().getStringArray(R.array.CREATE_TABLE_SQL); } @Override protected String[] getDbUpdateSql(Context context) { return context.getResources().getStringArray(R.array.UPDATE_TABLE_SQL); }
從配置文件當中獲取數據庫信息,這樣之後每次修改只須要修改xml文件就能夠了。
到此,一個數據庫操做類就完成啦,固然你能夠根據本身的須要在其實添加更多的便捷操做方法。
這裏提供的操做類,在使用的時候咱們還在須要在Activity中寫一些查詢的sql代碼,咱們能夠再搞一個統一作各類具體操做表的對象。
以爲不錯別忘記點贊喲!
最後送給你們一個雞湯,共勉
他每作一件小事的時候 他都像救命稻草同樣抓着 有一天我一看 嚯 好傢伙 他抱着的是已是讓我仰望的參天大樹