Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android Sqlite操作之-- 自定義ORM關系實體映射類

android Sqlite操作之-- 自定義ORM關系實體映射類

編輯:關於Android編程

任何android應用程序都少不了數據庫的操作,即使是客戶端程序也會有一些特定的數據存入到數據庫中,例如:用戶浏覽記錄,收藏列表等等,所以數據庫的操作就是一個會很頻繁使用的操作,所以對這個部分的封裝就很有必要了,Web端有Hibernate等一系列優秀的框架,雖然android應用程序在git上也有一些開源的OOM框架,但總覺得還是沒必要引入第三方的東西,於是就自己封裝了一個數據庫操作類,只要調用此類相應的方法,傳入要保存的實體對象或更新的實體對象即可,查詢也是同樣的,只要傳入查詢條件和Class,就返回對應的實體對象,這樣只要我們進行一次封裝,以後就可以直接用這個類去操作數據庫,而不必每次都寫繁雜的sql語句.下面就是我封裝類的部分代碼:

import com.micen.buyers.module.db.Module;

/**********************************************************
 * @文件名稱:DBDataHelper.java
 * @創建時間:2014-2-10 下午02:41:51
 * @文件描述:數據庫操作助手類
 * @修改歷史:2014-2-10創建初始版本
 **********************************************************/
public final class DBDataHelper
{
	private static DBDataHelper dataHelper = null;
	private DBHelper dbHelper = null;
	private static final String SELECT = "select ";
	private static final String FROM = " from ";
	private static final String WHERE = " where ";
	private static final String ORDER_BY = " order by ";

	private DBDataHelper()
	{
		dbHelper = DBHelper.getInstance();
	}

	public static DBDataHelper getInstance()
	{
		if (dataHelper == null)
		{
			dataHelper = new DBDataHelper();
		}
		return dataHelper;
	}

	/**
	 * 根據條件查詢數據庫表
	 * @param tableName
	 * @param showColumns
	 * @param selection
	 * @param selectionArgs
	 * @param orderBy
	 * @param cls
	 * @return
	 */
	public ArrayList select(String tableName, String showColumns, String selection, String selectionArgs,
			String orderBy, Class cls)
	{
		synchronized (dbHelper)
		{
			ArrayList moduleList = new ArrayList();
			SQLiteDatabase db = null;
			try
			{
				db = dbHelper.getReadableDatabase();
				String sql = SELECT;
				sql += showColumns != null ? showColumns : "*";
				sql += FROM + tableName;
				if (selection != null && selectionArgs != null)
				{
					sql += WHERE + selection + " = " + selectionArgs;
				}
				if (orderBy != null)
				{
					sql += ORDER_BY + orderBy;
				}
				Cursor cursor = db.rawQuery(sql, null);
				changeToList(cursor, moduleList, cls);
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				dbHelper.closeDatabase(db);
			}
			return moduleList;
		}
	}

	/**
	 * 查找數據表
	 * 
	 * @param table
	 *            要操作的表
	 * @param selection
	 *            匹配條件,例如"id>?and name <>?",不需要可以設為null
	 * @param selectionArgs
	 *            與selection相對應,裡面的字符串將替換selection裡的"?",
	 *            構成完整的匹配條件,例如{"6","jack"}
	 * @param orderby 排序參數
	 * @param moduleClass
	 *            要轉化成的模型類Class,例如要轉成WebPage則傳入WebPage.class
	 * @return 數據模型集合,集合是的對象類型為moduleClass
	 */
	public ArrayList select(final String table, final String selection, final String[] selectionArgs,
			final String orderby, final Class moduleClass)
	{
		SQLiteDatabase database = null;
		Cursor cursor = null;
		ArrayList moduleList = new ArrayList();
		synchronized (dbHelper)
		{

			try
			{
				database = dbHelper.getReadableDatabase();
				// 查詢數據
				cursor = database.query(table, null, selection, selectionArgs, null, null, orderby, null);
				// 將結果轉換成為數據模型
				changeToList(cursor, moduleList, moduleClass);
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				dbHelper.closeDatabase(database);
			}
			return moduleList;
		}
	}

	private void changeToList(Cursor cursor, List modules, Class moduleClass)
	{
		// 取出所有的列名
		int count = cursor.getCount();
		Module module;
		cursor.moveToFirst();
		synchronized (dbHelper)
		{
			try
			{
				// 遍歷游標
				for (int i = 0; i < count; i++)
				{
					// 轉化為moduleClass類的一個實例
					module = changeToModule(cursor, moduleClass);
					modules.add(module);
					cursor.moveToNext();
				}
			}
			catch (SecurityException e)
			{
				// Log.e(TAG, e + FusionCode.EMPTY_STRING);
			}
			catch (IllegalArgumentException e)
			{
				// Log.e(TAG, e + FusionCode.EMPTY_STRING);
			}
			catch (IllegalAccessException e)
			{
				// Log.e(TAG, e + FusionCode.EMPTY_STRING);
			}
			catch (InstantiationException e)
			{
				// Log.e(TAG, e + FusionCode.EMPTY_STRING);
			}
			catch (NoSuchFieldException e)
			{
				System.out.println("");
			}
			finally
			{
				cursor.close();
			}
		}
	}

	private Module changeToModule(Cursor cursor, Class moduleClass) throws IllegalAccessException,
			InstantiationException, SecurityException, NoSuchFieldException
	{
		synchronized (dbHelper)
		{
			// 取出所有的列名
			String[] columnNames = cursor.getColumnNames();
			String filedValue;
			int columncount = columnNames.length;
			Field field;
			Module module = (Module) moduleClass.newInstance();
			// 遍歷有列
			for (int j = 0; j < columncount; j++)
			{
				// 根據列名找到相對應 的字段
				field = moduleClass.getField(columnNames[j]);
				filedValue = cursor.getString(j);
				if (filedValue != null)
				{
					field.set(module, filedValue.trim());
				}
			}
			return module;
		}
	}

	/**
	 * 向數據庫插入數據
	 * 
	 * @param table
	 *            要操作的表
	 * @param module
	 *            數據模型,id設為自增,若沒指定,則自動生成;若指定則插入指定的id,
	 *            但是在數據表已存在該id的情況下會導致插入失敗,建議不指定id
	 * @return 插入行的行號,可以看作是id
	 */
	public long insert(final String table, final Module module)
	{
		synchronized (dbHelper)
		{
			ContentValues values = moduleToContentValues(module);
			return dbHelper.insert(table, null, values);
		}
	}

	/**
	 * 向數據庫更新數據
	 * 
	 * @param table
	 *            要操作的表
	 * @param module
	 * @return 更新行的行號,可以看作是id
	 */
	public long update(final String table, final Module module)
	{
		synchronized (dbHelper)
		{
			ContentValues values = moduleToContentValues(module);
			return dbHelper.update(table, values, DBHelper.ID + "=?", new String[]
			{ module.id });
		}
	}

	/**
	 * 刪除一條數據記錄
	 * 
	 * @param table
	 *            要操作的表
	 * @param module
	 *            數據模型,該操作是根據id刪除的,若id為null或不正確是不能成功刪除的
	 * @return 數據表受影響的行數,0或1
	 */
	public int delete(final String table, final Module module)
	{
		synchronized (dbHelper)
		{
			return dbHelper.delete(table, "id=?", new String[]
			{ module.id });
		}
	}

	/**
	 * 刪除數據
	 * 
	 * @param table
	 *            要操作的表
	 * @param whereClause
	 *            匹配條件,例如"id>?and name <>?",符合條件的記錄將被刪除,
	 *            不需要可以設為null,這樣整張表的內容都會被刪除
	 * @param whereArgs
	 *            與selection相對應,裡面的字符串將替換selection裡的"?",
	 *            構成完整的匹配條件,例如{"6","jack"}
	 * @return 數據表受影響的行數
	 */
	public int delete(final String table, final String whereClause, final String[] whereArgs)
	{
		synchronized (dbHelper)
		{

			return dbHelper.delete(table, whereClause, whereArgs);

		}
	}

	/**
	 * 將Module類型轉成ContentValues
	 * 
	 * @param module
	 *            源Module
	 * @return ContentValues
	 * @author shenghua.lin
	 */
	private ContentValues moduleToContentValues(final Module module)
	{
		  ContentValues values = new ContentValues();
		  Field[] fields = module.getClass().getFields();
		  String fieldName;
		  String fieldValue;
		  int fieldValueForInt = -1;
		try
		{
			for (Field field : fields)
			{
				fieldName = field.getName();
				if (field.get(module) instanceof String)
				{
					fieldValue = (String) field.get(module);
					if (fieldValue != null)
					{
						values.put(fieldName, fieldValue.trim());
					}
					else
					{
						values.put(fieldName, "");
					}
				}
				else if (field.get(module) instanceof Integer)
				{
					fieldValueForInt = (Integer) field.get(module);
					if (fieldValueForInt != -1)
					{
						values.put(fieldName, fieldValueForInt);
					}
				}
			}
		}
		catch (IllegalArgumentException e)
		{
		}
		catch (IllegalAccessException e)
		{
		}
		return values;
	}
}

思路: 對Sqlite的CRUD操作,其實就是實體類與android ContentValues的相互轉化,那麼我們通過反射,是可以做到兩種類間的相互轉化的,也就可以實現ORM映射了.避免了引入第三方庫的學習成本.


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved