1. 程式人生 > >利用反射實現對sqlite3資料庫的crud(增刪改查)操作的一個baseAndroidDao封裝,安卓開發中

利用反射實現對sqlite3資料庫的crud(增刪改查)操作的一個baseAndroidDao封裝,安卓開發中

1.說明

博主主要是做java web後臺這一塊,但是偶爾做點安卓,發現安卓上沒有像Hibernate這種orm框架(....其實也沒有去找),

又覺得每次增刪改查都自己寫程式碼的話肯定是非常麻煩的,所以就寫了一個簡單的baseAndroidDao來封裝一些簡單的增刪改查操作;

需要注意的是,此框架並非一個健全的orm框架,功能簡單,而且這些功能必須採用博主約定的方式才能正確執行;

2.具體實現

例舉現在有一個javaBean如下,其如同Hibernate中的實體,但是卻只是通過屬性來存取值(博主嫌麻煩....沒有用getter和setter那種標準方式,而且基本夠用...)

public class User extends BaseEntity {

    public Long Id;	
    public String Login_Name;
    public String Password;
    public String Real_Name;
    public Long State;
    public String Uid;
    @Entity_FieldProperty(FieldType=FieldType.JsonObject,cls=Sys_User_Info.class)
    public Sys_User_Info UserInfo;
	@Override
	public Long getId() {
		return Id;
	}
}

約定一:所有實體(用來儲存和資料庫表資料相對應的bean)必須繼承BaseEntity類,

約定二:同時屬性的名稱必須和資料庫中的欄位相一致;不過,主鍵必須是Long Id(不區分大小寫),資料庫中將會以_id欄位儲存;

約定三:只支援Boolean,Date,Long,String,Integer,List,Objec,Float,Double這幾個包裝類的屬性,不支援陣列型別;

約定四.通過Entity_FieldProperty註解來實現對List,bean物件,靜態物件的控制;

說明:這些約定都是很好改的.....如有需要可以下載之後自己該,最好是改成類似Hibernate那種註解識別id的方式,然後給博主發一份過來嘿嘿;

其中BaseEntity主要是封裝一些對Entity的操作....具體程式碼如下(其實這些東東封裝到Dao中,然後用Dao對Entity操作時最好的,這樣Entity也不用繼承BaseEntity)

以後有時間博主會重寫結構然後更新(現在結構很垃圾..耦合重...),但是利用反射的核心程式碼不會這麼變,所以大家可以看看:

/**
 * Entity約定:
 * 0.主鍵的名稱必須是id,不分大小寫,資料庫中以_id儲存
 * 1.只支援Boolean,Date,Long,String,Integer,List,Objec,Float,Double這幾個包裝類的屬性,不支援陣列型別
 * 2.其它屬性的值,不支援自動賦值與使用
 * 3.通過Entity_FieldProperty註解來實現對List,bean物件,靜態物件的控制;
 * @author dview
 *
 */
public abstract class BaseEntity {
	/**
	 * 下面規定允許的資料型別
	 */		
	@JSONField(serialize=false)
	private final String type_boolean="class java.lang.Boolean",
		   type_date="class java.util.Date",
		   type_float="class java.lang.Float",
		   type_double="class java.lang.Double",
		   type_long="class java.lang.Long",
		   type_integer="class java.lang.Integer",
		   type_string="class java.lang.String";
	@JSONField(serialize=false)
	public final static String primaryKeyName="_id";

	/**
	 * 判斷一個屬性是否是靜態變數,此類暫時不用
	 * @param field
	 */
	@JSONField(serialize=false)
	public boolean isStaticField(Field field){
		  boolean isStatic = Modifier.isStatic(field.getModifiers());
		  return isStatic;
	}
	/**
	 * 為本實體類賦值
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 */
	@JSONField(serialize=false)
	private void setFieldValue(Cursor c) throws IllegalAccessException, IllegalArgumentException{
		 if(c==null) return;
			Class<?> clazz=this.getClass();
			Field[] fs=clazz.getDeclaredFields();		
			for(Field f:fs){
				int index=0;//cursor遊標中的索引,某個欄位
				try{
				f.setAccessible(true);//強制獲取,設定值
				Annotation[] as=f.getAnnotations();
				Class<?> fclass=null;
				FieldType fType=null;
				   for(int i=0;i<as.length;i++){
					   Annotation a=as[i];
					   if(a instanceof Entity_FieldProperty){
						   Entity_FieldProperty ef=(Entity_FieldProperty)a;
						   if(ef!=null){
						   fclass=ef.cls();
						   fType=ef.FieldType();
						   }
						   break;
					   }
				   }
				 String typeString=f.getGenericType().toString();
				 String name=f.getName();
				 if(name.toLowerCase(Locale.ENGLISH).equals("id"))
				 {
					 name=primaryKeyName;
				 }
				  index=c.getColumnIndex(name);
				  if(index==-1)
					  continue;
				   //按照基礎六類屬性來處理
				   if(fType==null||fType==FieldType.Base){
					   		if(typeString.equals(type_boolean)){
					   			int result=c.getInt(index);
					   			f.set(this, (Boolean)(result==1));
					   		}else if(typeString.equals(type_date)){
							  Long m=c.getLong(index);
							  if(m!=null)
							   {
								  f.set(this, new Date(m));
							   }else{
								   f.set(this,null);
							   }							  
							}else if(typeString.equals(type_integer)){
								 f.set(this,c.getInt(index));
							}else if(type_long.equals(typeString)){
								f.set(this,c.getLong(index));
							}else if(typeString.equals(type_float)){
								f.set(this,c.getFloat(index));
							}else if(typeString.equals(type_double)){
								f.set(this,c.getDouble(index));
							}else{
								 f.set(this,c.getString(index));
							}
				   }else if(fType==FieldType.Transient){
				       continue;
				   }else if(fType==FieldType.JsonObject){
					   Object jobj=null;
					   if(c.getString(index)!=null)
					   JsonUtils_wg.parseToObject(c.getString(index), fclass);
					   f.set(this,jobj);
				   }else if(fType==FieldType.JsonList){
					   List<?> objs = null;
					   if(c.getString(index)!=null)
					   objs=JsonUtils_wg.parseToArray(c.getString(index), fclass);
					   f.set(this,objs);
				   }
				} catch (Exception e) {
					Log.e(this.getClass().getName(), e.toString());
					e.printStackTrace();
				    continue;
				}//end try
			}//end for
	}
   /**
    * 以鍵值對的方式,返回單籤類的,屬性的名稱和之所對應的值
    * @return
    * @param isChangeIdString 是否改變屬性名稱為id的鍵為BaseEntity.primaryKeyName所代表的屬性值
    * @throws IllegalArgumentException 
    * @throws IllegalAccessException 
    */
   @JSONField(serialize=false)
   private Map<String,Object> getFieldValue(boolean isChangeIdString) throws IllegalAccessException, IllegalArgumentException{
	   Map<String,Object> maps=new HashMap<String,Object>();
	   Class<?> clazz=this.getClass();
	   Field[] fs=clazz.getDeclaredFields();		
	   for(Field field:fs){
		   field.setAccessible(true);
		   Annotation[] as=field.getAnnotations();
		   Class<?> fclass=null;
		   FieldType fType=null;
		   for(int i=0;i<as.length;i++){
			   Annotation a=as[i];
			   if(a instanceof Entity_FieldProperty){
				   Entity_FieldProperty ef=(Entity_FieldProperty)a;
				   if(ef!=null){
					   fclass=ef.cls();
					   fType=ef.FieldType();
				   }
				   break;
			   }
		   }
		   String typeString=field.getGenericType().toString();
		   String name=field.getName();
		   if(name.toLowerCase(Locale.ENGLISH).equals("id")&&isChangeIdString)
			 {
				 name=primaryKeyName;
			 }
		   //按照基礎六類屬性來處理
		   if(fType==null||fType==FieldType.Base){		  
			   if(field.get(this)==null){
					  maps.put(name, null);
				  }else if(typeString.equals(type_boolean)){
					  if((Boolean)field.get(this))
				       {
						  maps.put(name,1);
				       }
				        else{
				        	maps.put(name,0);
					  }
				  }else if(typeString.equals(type_date)){
					  Date d=(Date) field.get(this);
					  maps.put(name, d.getTime());
				  }else {
					  maps.put(name,field.get(this));  
				  }		   
		   }else if(fType==FieldType.Transient){
		       continue; 
		   }else if(fType==FieldType.JsonObject){
			   if(field.get(this)==null)
			   {
				   maps.put(name,"{}");
			   }else{
				   String jsonString=JSON.toJSONString(field.get(this));
				   maps.put(name,jsonString);  
			   }
		   }else if(fType==FieldType.JsonList){
			   if(field.get(this)==null)
			   {
				   maps.put(name,"[]");
			   }else{
				   String jsonString=JSON.toJSONString(field.get(this));
				   maps.put(name,jsonString);  
			   }
		   }
	   }	
	   return maps;
   }
	//通過Cursor自動將值賦值到實體
	@JSONField(serialize=false)
	public void initFromCursor(Cursor c) throws IllegalAccessException, IllegalArgumentException{
		setFieldValue(c);						
	}
	
	
	@JSONField(serialize=false)
	public ContentValues getContentValues() throws IllegalAccessException, IllegalArgumentException
	{
		ContentValues cv;
		cv=new ContentValues();
		Map<String,Object> maps=getFieldValue(true);
		Set<String> keys=maps.keySet();		
		for(String s:keys){
			try{  Object obj=maps.get(s);			 
				  String typeString=obj.getClass().getName();
				  if(obj==null){
					  cv.put(s,"");
				  }else if(typeString.equals(type_boolean)){
					  cv.put(s,(Boolean)(obj));  
				  }else if(typeString.equals(type_date)){
					  cv.put(s,((Date)(obj)).getTime());  
					}else if(typeString.equals(type_integer)){
						cv.put(s,(Integer)(obj));  
					}else if(type_long.equals(typeString)){
						cv.put(s,((Long)(obj)));  
					}else if(typeString.equals(type_float)){
						cv.put(s,(Float)(obj));  
					}else if(typeString.equals(type_double)){
						cv.put(s,(Double)(obj));  
					}else if(typeString.equals(type_string)){
						cv.put(s,(String)(obj));
					}else{
						cv.put(s,JSON.toJSONString(obj));  
					}
			} catch (Exception e) {
				Log.e(this.getClass().getName(), e.toString());
				e.printStackTrace();
			    continue;
			}		
		}//end for
		return cv;
	}
	/**
	 * 返回該類屬性的鍵值對,鍵和值均為String型別
	 * @return
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 */
	@JSONField(serialize=false)
	public Map<String,Object> getMapValues() throws IllegalAccessException, IllegalArgumentException
	{
	   return getFieldValue(false);	
	}
	
	
	@JSONField(serialize=false)
	public void saveToDataBase(String tableName,SQLiteDatabase db) throws Exception{		
		if(getId()==0)
			throw new Exception("儲存的_id號碼不能夠是0,請稍後再試!");
		Map<String,Object> maps=getFieldValue(true);
		Set<String> keys=maps.keySet();		
		Object[] objs=new Object[keys.size()];
		String q="";
		String sql="insert into "+tableName.trim()+"(";
		int i=0;
		for(String s:keys){
			Object obj=maps.get(s);
			 if(i!=0)
			  {
				  sql+=",";
			      q+=",";
			  }
			  sql+=s;
			  q+="?";
			  objs[i]=obj;
			i++;			
		}
		sql+=") values ("+q+")";
		db.execSQL(sql, objs);
	}	
	
	@JSONField(serialize=false)
	public void updateToDataBase(String tableName,SQLiteDatabase db) throws Exception{
		if(getId()==0)
			throw new Exception("更新的_id號碼不能夠是0,請稍後再試!");
		this.updateToDataBaseByColumn(tableName, db, primaryKeyName);
	}
	/**
	 * 
	 * @param tableName
	 * @param db
	 * @param columnName 指定此此表的一個列名稱,更新所有相同的記錄
	 * @throws Exception
	 */
	@JSONField(serialize=false)
	public void updateToDataBaseByColumn(String tableName,SQLiteDatabase db,String columnName) throws Exception{
		if(columnName==null)
			throw new Exception("更新的columnName不能夠是null,請稍後再試!");
		Map<String,Object> maps=getFieldValue(true);
		Set<String> keys=maps.keySet();		
		Object[] objs=new Object[keys.size()+1];
		String sql="update "+tableName.trim()+" set ";
		int i=0;
		for(String s:keys){
			Object obj=maps.get(s);
			if(i!=0)
			  {
				  sql+=",";
			  }
			  sql+=s+"=?";		  
			  objs[i]=obj;
			  if(s.equals(columnName)){
	              objs[keys.size()]=obj;
			  }
			i++;			
		}		
		sql=sql+" where "+columnName+"=?";		
		db.execSQL(sql, objs);  
		 //data.close();
	}
	
	/**
	 * 
	 * @param tableName
	 * @param data
	 * @param notUpdateColumns 不需要跟新的欄位,區分大小寫
	 * @throws Exception 
	 */
	@JSONField(serialize=false)
	public void updateToDataBase(String tableName,SQLiteDatabase db,String[] notUpdateColumns) throws Exception{
		if(getId()==0)
			throw new Exception("更新的_id號碼不能夠是0,請稍後再試!");		
		Map<String,Object> maps=getFieldValue(true);
		Set<String> keys=maps.keySet();		
		Object[] objs;
		Map<String,Object> updateMap=new HashMap<String,Object>();
		String sql="update "+tableName.trim()+" set ";
		int i=0;
		for(String s:keys){//篩選出來需要更新的資料
			  boolean need=true;
		      if(notUpdateColumns!=null)
			  for(String c:notUpdateColumns){
					if(c.equals(s))
					{
						need=false;
						break;
					}
				}
		      if(need){
		    	  updateMap.put(s,maps.get(s));
		      }
        }		
		Set<String> key=updateMap.keySet();
		objs=new Object[key.size()+1];
		i=0;
		for(String s:key){
			Object value=updateMap.get(s);
			if(i!=0)
			  {
				  sql+=",";
			  }
			  sql+=s+"=?";
			  objs[i]=value;
			  if(s.equals(primaryKeyName))
			  {	objs[key.size()]=value; }
		  i++;
		}		
		sql=sql+" where "+primaryKeyName+"=?";	
		db.execSQL(sql, objs);
	}

	@Override
	public boolean equals(Object o) {
		if(this.getClass().getName().equals(o.getClass().getName())&&this.getId()-((BaseEntity)o).getId()==0)
			return true;
		return super.equals(o);
	}


	@Override
	public int hashCode() {
		return getId().intValue();
	}	
	
	public abstract Long getId();
	
}

其中Entity_FieldProperty這個註解主要是幫助我們對物件和List進行儲存以及讀取,說白了就是簡單的將之轉化為json字串,然後進行相關的序列號與反序列化;

/**
 * 指定當前Entity中的屬性的屬性,即自生的類別和轉換的方式
 * @author dview76
 * 當FieldType.Base的時候,將會按照預設識別的型別使用,即此時的cls屬性不會生效
 * JsonList,JsonObject,Base,Transient
 * JsonList,JsonObject表示此物件需要轉換為一個json物件或者字串;
 * Transient表示此物件,不進行資料庫的存和取操作,選擇Transient的時候,cls屬性不會生效
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Entity_FieldProperty {
	
	/**
	 * 指定一個型別是FieldType的,表現為FieldType=預設為FieldType.Base的Annotation
	 * @return
	 */
	FieldType FieldType() default FieldType.Base;
	/**
	 * 指定一個型別是Class的,表現為cls=預設為String.class的Annotation
	 * @return
	 */
	Class cls() default String.class;
	/**
     * 指定當前屬性的型別
     *
     */
    public enum FieldType{   	  
    	JsonList,JsonObject,Base,Transient;
    	};
     
    	
}


之後是主角BaseAndroidDao,其實就是增刪改查方法的封裝:

約定如下:此dao中不會管理事務;

/**
 * Dao中不會管理事務,事務在Service層中進行管理
 * @author dview
 *
 */
public class BaseAndroidDao<T extends BaseEntity> {
	private String tableName;
	private  DataBaseManager dbManager; 
	public BaseAndroidDao(String tableName) {
		super();
		this.dbManager=DataBaseManager.getInstance();
		this.tableName = tableName;
	}
		
	public SQLiteDatabase openDataBase(){
		  return dbManager.openDatabase(); 
	}
	
	public void closeDataBase(){
		dbManager.closeDatabase();
	}
	
	/**
	 * 得到當前的最大的id號碼的值
	 * @param db
	 * @return
	 */
	public Long getMaxId(SQLiteDatabase db){
		Cursor c=null;  	
		c=this.getCursor(db,tableName,null,"select max("+T.primaryKeyName+") ", null,null,null,null,null);
    	if(c.moveToNext()){
    		return c.getLong(c.getColumnIndex(T.primaryKeyName));
    	}else return null;
	}
	
	/**
	 * 得到當前的最小的id號碼的值
	 * @param db
	 * @return
	 */
	public Long getMinId(SQLiteDatabase db){
		Cursor c=null;  	
		c=this.getCursor(db,tableName,null,"select min("+T.primaryKeyName+") ", null,null,null,null,null);
    	if(c.moveToNext()){
    		return c.getLong(0);
    	}else return null;
	}
	
	/**
	 * 得到當前的的記錄總數
	 * @param db
	 * @return
	 */
	public Long getCount(SQLiteDatabase db){
		Cursor c=null;  	
		c=this.getCursor(db,tableName,null,"select count(*) ", null,null,null,null,null);
    	if(c.moveToNext()){
    		return c.getLong(0);
    	}else return null;
	}
	/**
	 * 返回所儲存到資料庫中的列表
	 * @param entity
	 * @return
	 */
	protected List<String> getEntityColumnNameList(Class<?> cls){
		   List<String> list=new ArrayList<String>();
		   Class<?> clazz=cls;
		   Field[] fs=clazz.getDeclaredFields();		
		   String filedName=null;
		   for(Field field:fs){
			   field.setAccessible(true);
			   filedName=field.getName();
			   Annotation[] as=field.getAnnotations();
			   Class fclass=null;
			   FieldType fType=null;
			   for(int i=0;i<as.length;i++){
				   Annotation a=as[i];
				   if(a instanceof Entity_FieldProperty){
					   Entity_FieldProperty ef=(Entity_FieldProperty)a;
					   if(ef!=null){
						   fclass=ef.cls();
						   fType=ef.FieldType();
						}
					   break;
				   }
			   }
			   if(fType==null||fType!=FieldType.Transient)
			   list.add(filedName);
		   }
		   return list;
	}
	
	/*
	 *得到除開指定名稱的屬性列 
	 */
	public String[] getEntityColumnNames(Class<?> cls,Boolean isRepacePrimaryKeyName,String... exceptCoulums){
		List<String> nameList=getEntityColumnNameList(cls);
		if(isRepacePrimaryKeyName==null){
			isRepacePrimaryKeyName=true;
		}
		if(exceptCoulums!=null){
			for(String s:exceptCoulums){
				nameList.remove(s);
			}
		}
		String[] names=new String[nameList.size()];
		for(int i=0;i<nameList.size();i++){
			names[i]=nameList.get(i);
			if(names[i].toLowerCase(Locale.ENGLISH).equals("id")){
				names[i]=BaseEntity.primaryKeyName;
			}
		}
		return names;
	}
	
	/**失敗返回null
	 *  傳入代Id值的Entity的值例項
	 * @param t 返回t
	 * @return
	 * @throws Exception 
	 */
	public T get(SQLiteDatabase db,T t) throws Exception{	    	  
    	if(t==null) return null;
    	Cursor c=null;
    	try {   		
			c=this.getCursor(db,tableName, null, T.primaryKeyName+"=?", new String[]{t.getId()+""}, null, null, null,null);
	    	if(c.moveToNext())
	    	{ t.initFromCursor(c);
	    	  return t;
	    	}else{
	    		return null;
	    	}
		} catch (Exception e) {
			Log.e(this.getClass().getName()+"T get:",e.toString());
			throw e;
		}finally{
			if(c!=null) c.close();			
		}   		       	
	}
	/**手動的條件搜尋
	 * @return
	 * @throws Exception 
	 */
	public T get(SQLiteDatabase db,Class<T> cls,String[] columns,String selection, String[] selectionArgs, String orderBy) throws Exception{	    	  
    	Cursor c=null;
    	try {   		
			c=this.getCursor(db,tableName,columns, selection, selectionArgs, null, null, orderBy,"0,1");
	    	if(c.moveToNext())
	    	{ T t=cls.newInstance();
	    	  t.initFromCursor(c);
	    	  return t;
	    	}else{
	    		return null;
	    	}
		} catch (Exception e) {
			Log.e(this.getClass().getName()+"T get:",e.toString());
			throw e;
		}finally{
			if(c!=null) c.close();			
		}   		       	
	}
	
	/**失敗返回null
	 *  傳入代Id值的Entity的值例項
	 * @param t 返回t
	 * @param exceptCoulums 不需要取出的資料列的名稱
	 * @return
	 * @throws Exception 
	 */
	public T get(SQLiteDatabase db,T t,String... exceptCoulums) throws Exception{	    	  
    	if(t==null) return null;
    	Cursor c=null;
    	try {
    		String[] names=getEntityColumnNames(t.getClass(), true,exceptCoulums);
 			c=this.getCursor(db,tableName,names, T.primaryKeyName+"=?", new String[]{t.getId()+""}, null, null, null,null);
	    	if(c.moveToNext())
	    	{ t.initFromCursor(c);
	    	  return t;
	    	}else{
	    		return null;
	    	}
		} catch (Exception e) {
			Log.e(this.getClass().getName()+"T get:",e.toString());
			throw e;
		}finally{
			if(c!=null) c.close();			
		}   		       	
	}
	
	
	/**
	 * 
	 * 失敗返回空陣列
	 * @param db
	 * @param cls
	 * @param selection
	 * @param selectionArgs
	 * @param orderBy
	 * @param limit select * from table_name limit N,M //N序號從0開始
	 * @param exceptCoulums 指定不從資料庫取出的列
	 * @return
	 * @throws Exception
	 */
	 public List<T> getList(SQLiteDatabase db,Class<T> cls,String selection, String[] selectionArgs, String orderBy,String limit,String... exceptCoulums) throws Exception{
		 List<T> ts=new ArrayList<T>();
		 Cursor c = null;
		 try {
			 String[] names=getEntityColumnNames(cls, true, exceptCoulums);
			 c=this.getCursor(db,tableName,names, selection, selectionArgs, null, null, orderBy,limit);
			 while(c.moveToNext()){
				 T t=cls.newInstance();
				 t.initFromCursor(c);
				 if(!ts.contains(t))
				 ts.add(t);
			 }		 
		} catch (Exception e) {
			Log.e("getList:"+cls.getName(),e.toString());
			throw e;
		}finally{
			 if(c!=null) c.close();				
		}
		 return ts;
	    }
	/**
	 * 失敗返回空陣列
	 * @param db
	 * @param cls
	 *@param selection
	 * @param selectionArgs
	 * @param orderBy
	 * @param limit select * from table_name limit N,M //N序號從0開始
	 * @return
	 * @throws Exception 
	 */
	 public List<T> getList(SQLiteDatabase db,Class<T> cls,String selection, String[] selectionArgs, String orderBy,String limit) throws Exception{
		 List<T> ts=new ArrayList<T>();
		 Cursor c = null;
		 try {
			c=this.getCursor(db,tableName, null, selection, selectionArgs, null, null, orderBy,limit);
			 while(c.moveToNext()){
				 T t=cls.newInstance();
				 t.initFromCursor(c);
				 if(!ts.contains(t))
				 ts.add(t);
			 }		 
		} catch (Exception e) {
			Log.e("getList:"+cls.getName(),e.toString());
			throw e;
		}finally{
			 if(c!=null) c.close();				
		}
		 return ts;
	    }
	 /**
	  * 獲取資料庫中的所有的記錄
	  * @param db
	  * @param cls
	  * @return
	  * @throws Exception
	  */
	 public List<T> getList(SQLiteDatabase db,Class<T> cls) throws Exception{
		 List<T> ts=new ArrayList<T>();
		 Cursor c = null;
		 try {
			c=this.getCursor(db,tableName, null,null,null, null, null,null,null);
			 while(c.moveToNext()){
				 T t=cls.newInstance();
				 t.initFromCursor(c);
				 if(!ts.contains(t))
				 ts.add(t);
			 }		 
		} catch (Exception e) {
			Log.e("getList:"+cls.getName(),e.toString());
			throw e;
		}finally{
			 if(c!=null) c.close();				
		}
		 return ts;
	    }
	 
	 /**
	  * 
	  * @param t
	  * @return 插入返回1
	 * @throws Exception 
	  */
	 public void saveOrUpdate(SQLiteDatabase db,T t) throws Exception{
		 Cursor c = null;
		 try {
			c=this.getCursor(db,tableName, null, T.primaryKeyName+"=?", new String[]{t.getId()+""}, null, null, null,null);
		    	if(c.moveToNext())
		    	{//如果已經存在,則更新,否則insert
		    		t.updateToDataBase(tableName,db);
		    	    return;
		    	}		      
			 t.saveToDataBase(tableName,db);
			 return;
		} catch (Exception e) {
			Log.e("saveOrUpdate:"+t.getClass().getName(),e.toString());
			throw e;
		}finally{
			if(c!=null) c.close();
		}
	 }
	 
	 
	 /**
	  * 
	  * @param t
	  * @return 插入返回1
	  * @param columnName 如果指定的欄位,有相同的值存在於資料庫,那麼就更新資料庫,否則儲存
	  * @throws Exception
	  */
	 public void saveOrUpdate(SQLiteDatabase db,T t,String columnName) throws Exception{
		 Cursor c = null;
		 try {
			c=this.getCursor(db,tableName, null, columnName+"=?", new String[]{t.getClass().getField(columnName).get(t)+""}, null, null, null,null);
		    	if(c.moveToNext())
		    	{//如果已經存在,則更新,否則insert
		    		t.updateToDataBaseByColumn(tableName, db, columnName);
		    	    return;
		    	}		      
			 t.saveToDataBase(tableName,db);
			 return;
		} catch (Exception e) {
			Log.e("saveOrUpdate:"+t.getClass().getName(),e.toString());
			throw e;
		}finally{
			if(c!=null) c.close();
		}
	 }
	 
	 /**
	  * 先刪除,後儲存,沒有則不刪除
	  * @param db
	  * @param t
	  * @throws Exception
	  */
	 public void deleteAndSave(SQLiteDatabase db,T t) throws Exception{
		 try {
			 this.delete(db, t.getId()+"");
			 this.save(db, t);
		} catch (Exception e) {
			Log.e("saveOrUpdate:"+t.getClass().getName(),e.toString());
			throw e;
		}
	 }
	 
	 /**
	  * 
	  * @param db
	  * @param list
	  * @return
	 * @throws Exception 
	  */
	public void saveOrUpdateList(SQLiteDatabase db,List<T> list) throws Exception{
		try{
			for(T t:list){
				saveOrUpdate(db, t);					
			}
		}catch(Exception e){
			throw new Exception("saveOrUpdateList: "+" Fail");
		}
	}
	
	/**
	 * 
	 * @param db
	 * @param list
	 * @param column 指定列的值相同就更新,否則就儲存
	 * @throws Exception
	 */
	public void saveOrUpdateList(SQLiteDatabase db,List<T> list,String column) throws Exception{
		try{
			for(T t:list){
				saveOrUpdate(db, t,column);					
			}
		}catch(Exception e){
			throw new Exception("saveOrUpdateList: "+" Fail");
		}
	}
	
	/**
	  *刪除後儲存所有 
	  * @param db
	  * @param list
	  * @return
	 * @throws Exception 
	  */
	public void deleteAndSaveList(SQLiteDatabase db,List<T> list) throws Exception{
		try{
			for(T t:list){
				deleteAndSave(db, t);					
			}
		}catch(Exception e){
			throw new Exception("saveOrUpdateList: "+" Fail");
		}
	}
	
	 public int update(SQLiteDatabase db,T t) throws Exception{
		 try {
			t.updateToDataBase(tableName,db);
    	    return 2;
		} catch (Exception e) {
			Log.e("update:"+t.getClass().getName(),e.toString());
			throw e;
		}
	 }
	 /**
	  * 
	  * @param t
	  * @param notUpdateColumns 不需要更新的欄位名稱的陣列
	  * @return
	 * @throws Exception 
	  */
	 public int update(SQLiteDatabase db,T t,String[] notUpdateColumns) throws Exception{
		 try {
			t.updateToDataBase(tableName,db,notUpdateColumns);
    	    return 2;
		} catch (Exception e) {
			Log.e("update:"+t.getClass().getName(),e.toString());
			throw e;
		}
	 }
	 
	public int save(SQLiteDatabase db,T t) throws Exception{
		 try {		 
			 t.saveToDataBase(tableName, db);
			 return 1;
		} catch (Exception e) {
			Log.e("save:"+t.getClass().getName(),e.toString());
			throw e;
		}
	 }
	 
	 public int delete(SQLiteDatabase db,String id) throws Exception{
		 if(id.equals("0"))
				throw new Exception("刪除的_id號碼不能夠是0,請稍後再試!");  
		 try {
	   		this.delete(db,tableName, id);
	   		return 1;
		} catch (Exception e) {
			Log.e("delete:"+this.getClass().getName(),e.toString());
			throw e;
		}
	 }
	 
	 public int deleteList(SQLiteDatabase db,String ids) throws Exception{
		   try {
			   String whereClause=" "+T.primaryKeyName+" in (?)";
			   String[] whereArgs=new String[]{ids};
			   this.delete(db,tableName, whereClause, whereArgs);
		    return 1;
		   } catch (Exception e) {
				Log.e("deleteList:"+this.getClass().getName(),e.toString());
				throw e;
		}
	 }
	 
	 public int deleteAll(SQLiteDatabase db) throws Exception{
		 try {
			 this.delete(db,tableName, null,null);
		    return 1;
		   } catch (Exception e) {
				Log.e("deleteAll:"+this.getClass().getName(),e.toString());
				throw e;
		}
	 }	 
	 
	 /**
	  * 返回搜尋的cursor;
	  * @param db
	  * @param sqlString
	  * @param selectionArgs sql中?佔位符的引數
	  * @return
	  */
	 public Cursor getCursor(SQLiteDatabase db,String sqlString,String[] selectionArgs){
		 return db.rawQuery(sqlString,selectionArgs);
	 }
	 
	 /**
	  * 
	  * @param db
	  * @param sqlString
	  * @param selectionArgs sql中?佔位符的引數
	  * @param columns 需要出去的列的名稱,沒有會賦值null;取出的列只支援float/string/blob/string/null這幾種型別;
	  * *其中二進位制會轉換成為byte[]型別;除開這些型別外,系統會預設用string來取出資料
	  * @return List<Object[]>
	  */
	 public List<Object[]> getColumns(SQLiteDatabase db,String sqlString,String[] selectionArgs,String...columns){
		 List<Object[]> list=new ArrayList<Object[]>();
		 Object[] objs=null;
		 Cursor cursor=getCursor(db, sqlString, selectionArgs);
		 while(cursor.moveToNext()){
		    objs=new Object[columns.length];
		    try{
			    for(int i=0;i<columns.length;i++){
			    	String ss=columns[i];
			        int index=cursor.getColumnIndex(ss);
			        if(index==-1)
			        continue;
			    	int columnType =cursor.getType(index);
			    	switch (columnType) {
			    	case Cursor.FIELD_TYPE_NULL:
			    		 objs[i]=null;
			    		 break;		    	
					case Cursor.FIELD_TYPE_INTEGER:
						objs[i]=cursor.getInt(index);
						 break;
					case Cursor.FIELD_TYPE_BLOB:
						objs[i]=cursor.getBlob(index);
						break;
					case Cursor.FIELD_TYPE_FLOAT:
						objs[i]=cursor.getFloat(index);
						break;
					case Cursor.FIELD_TYPE_STRING:
						objs[i]=cursor.getString(index);
					break;
					default:
						objs[i]=cursor.getString(index);
						break;
					}		    	
			    }
			    list.add(objs);
		    }catch(ClassCastException e){
		    	e.printStackTrace();
		    	Log.e("BaseAndroidDao:getColumns:",e.toString());
		    }		    
		 }
		 return list;
	 }
	 
	    public Cursor getCursor(SQLiteDatabase db,String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy,String limit) {
	        Cursor cursor = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy,limit); 
	    	  return cursor; 
	    	}
	    				
	    	public void execSQL(SQLiteDatabase db,String sql){
	    		 db.execSQL(sql);
	    	}
	    	
	    	public void execSQL(SQLiteDatabase db,String sql,Object[] objs){
	    		db.execSQL(sql,objs);
	    	}
	    	
	    	/**
	    	 * 呼叫原生的insert方法,不推薦
	    	 * @param tableName
	    	 * @param cv
	    	 * @return
	    	 */
	    	public long insert(SQLiteDatabase db,String tableName,ContentValues cv) 
	    	{ 
	    		long row = db.insert(tableName, null, cv); 
	    		return row; 
	    	} 
	    	/**
	    	 * 呼叫自己寫的方法,insert into person(name,phone) values (?,?)
	    	 * @param p
	    	 */
	    	public void save(SQLiteDatabase db,String sql,Object[] objs)  
	    	{
	    	 db.execSQL(sql, objs);  
	    	}  
	    	
	    	public void update(SQLiteDatabase db,String sql,Object[] objs){
	    		 db.execSQL(sql, objs);  
	    	}
	    	
	    	//刪除操作 
	    	public void delete(SQLiteDatabase db,String tableName,String id) 
	    	{
	    		String where =BaseEntity.primaryKeyName + "=?"; 
	    		String[] whereValue ={id}; 
	    		db.delete(tableName, where, whereValue);
	    	}
	    	
	    	//刪除操作 
	    	public void delete(SQLiteDatabase db,String table, String whereClause, String[] whereArgs) 
	    	{ 
	    		db.delete(table, whereClause, whereArgs); 
	    	}
	    	
	    	
	    	//修改操作 
	    	public void update(SQLiteDatabase db,String tableName,int id, ContentValues cv) 
	    	{ 
	    		String where = BaseEntity.primaryKeyName+ "=?"; 
	    		String[] whereValue = { Integer.toString(id) }; 
	    		db.update(tableName, cv, where, whereValue); 
	    	}
	    	
	    	//修改操作 
	    	public void update(SQLiteDatabase db,String tableName,ContentValues cv, String where,String[] whereValue) 
	    	{ 
	    			db.update(tableName, cv, where, whereValue); 
	    	}
	 
		public String getTableName() {
			return tableName;
		}

		public void setTableName(String tableName) {
			this.tableName = tableName;
		}	
		
}
這裡DataBaseManager實際上是一個管理資料庫連線的類,不需要的可以忽略,詳情見:http://blog.csdn.net/huitoukest/article/details/50469236

3:使用示例:

public class LoginTypeService {
private String tableName="loginType";
private BaseAndroidDao<LoginType> baseDao;

       public LoginTypeService(){
    	   baseDao=new BaseAndroidDao<LoginType>(tableName);
       }

       public LoginType getLoginType(){
    	   LoginType lt=new LoginType();
    	   lt.setId(1L);
    	 SQLiteDatabase db = null;
    	   try {
    		   db=baseDao.openDataBase();
    		   lt=baseDao.get(db, lt);
			   return lt;
		} catch (Exception e) {
			return null;
		}finally{
			baseDao.closeDataBase();
		}
       }
       
       public boolean saveOrUpdate(LoginType loginType){
    	   if(loginType==null||loginType.getId()==null)
    		   return false;
    	   SQLiteDatabase db = null;
    	   try {
    		   db=baseDao.openDataBase();
    		   db.beginTransaction();
    		   baseDao.saveOrUpdate(db, loginType);
    		   db.setTransactionSuccessful();
			   return true;
		} catch (Exception e) {
			return false;
		}finally{
			if(db!=null)
			db.endTransaction();
			baseDao.closeDataBase();
		}
    	   
       }
       
}

注意:Service層,就是是控制層來負責事務的管理;