开发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代码,咱们能够再搞一个统一作各类具体操做表的对象。
以为不错别忘记点赞哟!
最后送给你们一个鸡汤,共勉
他每作一件小事的时候 他都像救命稻草同样抓着 有一天我一看 嚯 好家伙 他抱着的是已是让我仰望的参天大树