1. 程式人生 > >Android利用泛型和反射來實現對資料庫的操作--SqlHelper

Android利用泛型和反射來實現對資料庫的操作--SqlHelper

利用泛型和反射來實現對資料庫的操作

1.對資料庫操作的介面類

package com.dou361.dal;

import java.util.List;


/**
 * @author jjdxm
 * http://www.dou361.com
 * http://blog.csdn.net/jiujiedexiaoming
 * 通過反射來對資料庫操作
 *
 * @param <T>
 */
public interface SqlHelper<T> {
	/**
	 * 新增
	 * @param table 新增對應的表
	 * @param t 表對應的物件
	 * @return 插入的位置索引
	 */
	long insert(String table,T t);
	/**
	 * 刪除
	 * @param table 刪除對應的表
	 * @param columname 通過的欄位
	 * @param vaule 欄位對應的值
	 * @return 刪除影響的行數
	 */
	int delete(String table,String columname,String vaule);
	/**
	 * 修改
	 * @param table 修改對應的表
	 * @param t 修改的表對應的物件
	 * @return 修改影響的行數
	 */
	int update(String table,T t);
	/**
	 * 查詢一個
	 * @param table 需要查詢的表
	 * @param columname 需要查詢的欄位名
	 * @param vaule 需要查詢的欄位對應的值
	 * @return 表對應的物件
	 */
	List<T> query(String table,String columname,String vaule);
	
	/**
	 * 查詢一頁
	 * @param table 需要查詢的表
	 * @param startIndex 查詢的起始索引
	 * @param pageSize 查詢的頁面條數
	 * @return page資料
	 */
	List<T> queryPage(String table,int startIndex,int pageSize);
	
	/**
	 * @param table 需要查詢的表
	 * @return 所有資料
	 */
	List<T> queryAll(String table);
}

2.對資料操作的實現類
package com.dou361.dal;

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

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

import com.dou361.db.DBOpenHelper;

/**
 * @author jjdxm 
 * http://www.dou361.com
 * http://blog.csdn.net/jiujiedexiaoming
 * 通過反射來對資料庫操作
 * @param <T>
 */
public class SqlHelperImpl<T> implements SqlHelper<T> {

	/**
	 * 反射得到位元組碼檔案
	 */
	private Class clazz;

	/**
	 * 對應表的對映欄位(操作表的所有屬性)
	 */
	private String[] sqlcolumns;

	/**
	 * 建立資料庫的幫助物件
	 */
	private DBOpenHelper dbOpenHelper;

	/**
	 * 建構函式,初始化工作
	 * 
	 * @param context
	 *            上下文
	 * @param clazz
	 *            表對應bean物件的位元組碼檔案
	 * @param dbName
	 *            資料庫名稱
	 * @param sql
	 *            建立表語句
	 * @param sqlcolumns
	 *            對應表的對映欄位(操作表的所有屬性)
	 */
	public SqlHelperImpl(Context context, Class clazz, String dbName,
			String sql, String[] sqlcolumns) {
		this.clazz = clazz;
		this.sqlcolumns = sqlcolumns;
		dbOpenHelper = new DBOpenHelper(context, dbName, sql);
	}

	@Override
	public long insert(String table, T t) {
		try {
			SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
			if (sqlcolumns != null && sqlcolumns.length > 0) {
				ContentValues values = new ContentValues();
				for (int i = 1; i < sqlcolumns.length; i++) {
					try {
						Field field = t.getClass().getDeclaredField(
								sqlcolumns[i]);
						field.setAccessible(true);
						Object objVaule = field.get(t);
						if (objVaule != null) {
							values.put(sqlcolumns[i], (String) objVaule);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				long insertIndex = database.insert(table, null, values);
				database.close();
				return insertIndex;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return -1;
	}

	@Override
	public int delete(String table, String columname, String value) {
		SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
		int rows = database.delete(table, columname + "=?",
				new String[] { value });
		database.close();
		return rows;
	}

	@Override
	public int update(String table, T t) {
		try {
			SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
			String whereValue = null;
			if (sqlcolumns != null && sqlcolumns.length > 0) {
				ContentValues values = new ContentValues();
				for (int i = 0; i < sqlcolumns.length; i++) {
					try {
						Field field = t.getClass().getDeclaredField(
								sqlcolumns[i]);
						field.setAccessible(true);
						Object objVaule = field.get(t);
						if (objVaule != null) {
							if (i == 0) {
								whereValue = objVaule.toString();
							} else {
								values.put(sqlcolumns[i], (String) objVaule);
							}
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				int rows = database.update(table, values, sqlcolumns[0] + "=?",
						new String[] { whereValue });
				database.close();
				return rows;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return -1;
	}

	@Override
	public List<T> query(String table, String columname, String value) {
		SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
		Cursor cursor = database.query(table, sqlcolumns, columname + "=?",
				new String[] { value }, null, null, null);
		List<T> list = new ArrayList<T>();
		while (cursor.moveToNext()) {
			try {
				Object obj = clazz.newInstance();
				for (int i = 0; i < sqlcolumns.length; i++) {
					try {
						Field field = clazz.getDeclaredField(sqlcolumns[i]);
						field.setAccessible(true);

						int type = cursor.getType(i);
						Object objValue = null;
						switch (type) {
						case Cursor.FIELD_TYPE_STRING:
							objValue = cursor.getString(i);
							break;
						case Cursor.FIELD_TYPE_INTEGER:
							objValue = cursor.getInt(i);
							break;
						case Cursor.FIELD_TYPE_FLOAT:
							objValue = cursor.getFloat(i);
							break;
						case Cursor.FIELD_TYPE_BLOB:
							objValue = cursor.getBlob(i);
							break;

						default:
							break;
						}

						field.set(obj, objValue);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				T t = (T) obj;
				list.add(t);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		cursor.close();
		database.close();
		return list;
	}

	@Override
	public List<T> queryPage(String table, int startIndex, int pageSize) {
		SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
		Cursor cursor = database.query(table, sqlcolumns, null, null, null,
				null, sqlcolumns[0] + " desc", startIndex + "," + pageSize);
		List<T> list = new ArrayList<T>();
		while (cursor.moveToNext()) {
			try {
				Object obj = clazz.newInstance();
				for (int i = 0; i < sqlcolumns.length; i++) {
					try {
						Field field = clazz.getDeclaredField(sqlcolumns[i]);
						field.setAccessible(true);

						int type = cursor.getType(i);
						Object objValue = null;
						switch (type) {
						case Cursor.FIELD_TYPE_STRING:
							objValue = cursor.getString(i);
							break;
						case Cursor.FIELD_TYPE_INTEGER:
							objValue = cursor.getInt(i);
							break;
						case Cursor.FIELD_TYPE_FLOAT:
							objValue = cursor.getFloat(i);
							break;
						case Cursor.FIELD_TYPE_BLOB:
							objValue = cursor.getBlob(i);
							break;

						default:
							break;
						}

						field.set(obj, objValue);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				T t = (T) obj;
				list.add(t);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		cursor.close();
		database.close();
		return list;
	}

	@Override
	public List<T> queryAll(String table) {
		SQLiteDatabase database = dbOpenHelper.getWritableDatabase();
		Cursor cursor = database.query(table, sqlcolumns, null, null, null,
				null, null, null);
		List<T> list = new ArrayList<T>();
		while (cursor.moveToNext()) {
			try {
				Object obj = clazz.newInstance();
				for (int i = 0; i < sqlcolumns.length; i++) {
					try {
						Field field = clazz.getDeclaredField(sqlcolumns[i]);
						field.setAccessible(true);
						int type = cursor.getType(i);
						Object objValue = null;
						switch (type) {
						case Cursor.FIELD_TYPE_STRING:
							objValue = cursor.getString(i);
							break;
						case Cursor.FIELD_TYPE_INTEGER:
							objValue = cursor.getInt(i);
							break;
						case Cursor.FIELD_TYPE_FLOAT:
							objValue = cursor.getFloat(i);
							break;
						case Cursor.FIELD_TYPE_BLOB:
							objValue = cursor.getBlob(i);
							break;

						default:
							break;
						}
						field.set(obj, objValue);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				T t = (T) obj;
				list.add(t);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		cursor.close();
		database.close();
		return list;
	}

}
3.通過以上的幫助類,可以開速的編寫對資料庫的操作類

如一個新聞的實體類和其對應的表

package com.dou361.domain;

import java.io.Serializable;

public class Acount implements Serializable {

	private static final long serialVersionUID = 1L;

	private Integer _id;
	private String acountName;

	public Integer get_id() {
		return _id;
	}

	public void set_id(Integer _id) {
		this._id = _id;
	}

	public String getAcountName() {
		return acountName;
	}

	public void setAcountName(String acountName) {
		this.acountName = acountName;
	}

}

4.具體的資料庫操作類
<pre name="code" class="java">package com.dou361.dao.impl;

import java.util.List;

import android.content.Context;

import com.dou361.dal.SqlHelperImpl;
import com.dou361.domain.Acount;

public class AcountDaoImpl extends SqlHelperImpl<Acount> {

	private String table = "T_Acounts";
	static String sql = "create table T_Acounts (_id Integer primary key autoincrement,acountName varchar(30))";
	static String[] sqlcolumns = new String[] { "_id", "acountName" };

	public AcountDaoImpl(Context context) {
		super(context, "mobilesafe.db", sql, Acount.class, sqlcolumns);
	}

	@Override
	public long add(Acount acount) {
		return super.insert(table, acount);
	}

	@Override
	public int deleteByValue(String columname, String value) {
		return super.delete(table, columname, value);
	}

	@Override
	public int update(Acount acount) {
		return super.update(table, acount);
	}

	@Override
	public List<Acount> getByValue(String columname, String value) {
		return super.query(table, columname, value);
	}

	@Override
	public List<Acount> getAll() {
		return super.queryAll(table);
	}

}



5.為了方便起見,還可以進一步優化
package com.dou361.bussiness.impl;

import java.util.List;

import android.content.Context;

import com.dou361.bussiness.AcountBusinessServer;
import com.dou361.dao.impl.AcountDaoImpl;
import com.dou361.domain.Acount;

public class AcountBusinessServerImpl implements AcountBusinessServer {

	private AcountDaoImpl<span style="font-family: Arial, Helvetica, sans-serif;"> </span>acountDao;

	public AcountBusinessServerImpl(Context context) {
		acountDao = new AcountDaoImpl(context);
	}
<span style="white-space:pre">	/**
<span style="white-space:pre">	</span> * 新增
<span style="white-space:pre">	</span> * 
<span style="white-space:pre">	</span> * @param Acount
<span style="white-space:pre">	</span> *            新增的Acount物件
<span style="white-space:pre">	</span> * @return 返回狀態
<span style="white-space:pre">	</span> */</span>
	@Override
	public boolean add(Acount acount) {
		return acountDao.add(acount) > 0;
	}
<span style="white-space:pre">	

<span style="white-space:pre">	</span>/**
<span style="white-space:pre">	</span> * 刪除
<span style="white-space:pre">	</span> * 
<span style="white-space:pre">	</span> * @param id
<span style="white-space:pre">	</span> *            通過id刪除一個BlackNumber物件
<span style="white-space:pre">	</span> * @return 返回狀態
<span style="white-space:pre">	</span> */</span>
	@Override
	public boolean deleteById(String id) {
		return acountDao.deleteByValue("_id", id) > 0;
	}
<span style="white-space:pre">	

<span style="white-space:pre">	</span>/**
<span style="white-space:pre">	</span> * 修改
<span style="white-space:pre">	</span> * 
<span style="white-space:pre">	</span> * @param Acount
<span style="white-space:pre">	</span> *            修改的acount物件
<span style="white-space:pre">	</span> * @return 返回狀態
<span style="white-space:pre">	</span> */</span>
	@Override
	public boolean update(Acount acount) {
		return acountDao.update(acount) > 0;
	}
<span style="white-space:pre">	

<span style="white-space:pre">	</span>/**
<span style="white-space:pre">	</span> * 查詢一個Acount物件
<span style="white-space:pre">	</span> * 
<span style="white-space:pre">	</span> * @param id
<span style="white-space:pre">	</span> *            通過id查詢
<span style="white-space:pre">	</span> * @return 返回Acount
<span style="white-space:pre">	</span> */</span>
	@Override
	public List<Acount> getById(String id) {
		return acountDao.getByValue("_id", id);
	}
	

<span style="white-space:pre">	</span>/**
<span style="white-space:pre">	</span> * 查詢一個Acount物件
<span style="white-space:pre">	</span> * 
<span style="white-space:pre">	</span> * @param acountName
<span style="white-space:pre">	</span> *            通過acountName查詢
<span style="white-space:pre">	</span> * @return 返回Acount
<span style="white-space:pre">	</span> */
	@Override
	public List<Acount> getByAcountName(String acountName) {
		return acountDao.getByValue("acountName", acountName);
	}
<span style="white-space:pre">	

<span style="white-space:pre">	</span>/**
<span style="white-space:pre">	</span> * @return 返回所有
<span style="white-space:pre">	</span> */</span>
	@Override
	public List<Acount> getAll() {
		return acountDao.getAll();
	}

}

6.接下來就是使用了,在這裡只需要建立最後一個類的例項即可方便的使用了。