Android sqlite数据库操作通用框架AHibernate(二)源码-用于交流
生活随笔
收集整理的這篇文章主要介紹了
Android sqlite数据库操作通用框架AHibernate(二)源码-用于交流
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
貼出源代碼供大家交流使用,歡迎朋友們對(duì)代碼提供寶貴意見(jiàn),直接寫到評(píng)論中即可.使用示例和步驟見(jiàn)上一篇博客:http://blog.csdn.net/lk_blog/article/details/7455992
源碼和示例下載地址: http://download.csdn.net/detail/lk_blog/4222048
(一)注解類:Table.java
[java] view plaincopy
<span style="font-size:18px;">package com.tgb.lk.ahibernate.annotation; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)
@Target( { java.lang.annotation.ElementType.TYPE })
public @interface Table { /** * 表名 * * @return */ public abstract String name();
}</span>
Column.java[java] view plaincopy
<span style="font-size:18px;">package com.tgb.lk.ahibernate.annotation; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)
@Target( { java.lang.annotation.ElementType.FIELD })
public @interface Column { /** * 列名 * * @return */ public abstract String name(); public abstract String type() default ""; public abstract int length() default 0;
}</span>
Id.java
[java] view plaincopy
<span style="font-size:18px;">package com.tgb.lk.ahibernate.annotation; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)
@Target( { java.lang.annotation.ElementType.FIELD })
public @interface Id {
}</span>
(二)Util類:TableHelper.java[java] view plaincopy
<span style="font-size:18px;">package com.tgb.lk.ahibernate.util; import android.database.sqlite.SQLiteDatabase;
import android.util.Log; import java.lang.reflect.Field;
import java.sql.Blob;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import com.tgb.lk.ahibernate.annotation.Column;
import com.tgb.lk.ahibernate.annotation.Id;
import com.tgb.lk.ahibernate.annotation.Table; public class TableHelper { private static final String TAG = "AHibernate"; public static <T> void createTablesByClasses(SQLiteDatabase db, Class<?>[] clazzs) { for (Class<?> clazz : clazzs) createTable(db, clazz); } public static <T> void dropTablesByClasses(SQLiteDatabase db, Class<?>[] clazzs) { for (Class<?> clazz : clazzs) dropTable(db, clazz); } public static <T> void createTable(SQLiteDatabase db, Class<T> clazz) { String tableName = ""; if (clazz.isAnnotationPresent(Table.class)) { Table table = (Table) clazz.getAnnotation(Table.class); tableName = table.name(); } StringBuilder sb = new StringBuilder(); sb.append("CREATE TABLE ").append(tableName).append(" ("); List<Field> allFields = TableHelper .joinFields(clazz.getDeclaredFields(), clazz.getSuperclass() .getDeclaredFields()); for (Field field : allFields) { if (!field.isAnnotationPresent(Column.class)) { continue; } Column column = (Column) field.getAnnotation(Column.class); String columnType = ""; if (column.type().equals("")) columnType = getColumnType(field.getType()); else { columnType = column.type(); } sb.append(column.name() + " " + columnType); if (column.length() != 0) { sb.append("(" + column.length() + ")"); } if (((field.isAnnotationPresent(Id.class)) && (field.getType() == Integer.TYPE)) || (field.getType() == Integer.class)) sb.append(" primary key autoincrement"); else if (field.isAnnotationPresent(Id.class)) { sb.append(" primary key"); } sb.append(", "); } sb.delete(sb.length() - 2, sb.length() - 1); sb.append(")"); String sql = sb.toString(); Log.d(TAG, "crate table [" + tableName + "]: " + sql); db.execSQL(sql); } public static <T> void dropTable(SQLiteDatabase db, Class<T> clazz) { String tableName = ""; if (clazz.isAnnotationPresent(Table.class)) { Table table = (Table) clazz.getAnnotation(Table.class); tableName = table.name(); } String sql = "DROP TABLE IF EXISTS " + tableName; Log.d(TAG, "dropTable[" + tableName + "]:" + sql); db.execSQL(sql); } private static String getColumnType(Class<?> fieldType) { if (String.class == fieldType) { return "TEXT"; } if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) { return "INTEGER"; } if ((Long.TYPE == fieldType) || (Long.class == fieldType)) { return "BIGINT"; } if ((Float.TYPE == fieldType) || (Float.class == fieldType)) { return "FLOAT"; } if ((Short.TYPE == fieldType) || (Short.class == fieldType)) { return "INT"; } if ((Double.TYPE == fieldType) || (Double.class == fieldType)) { return "DOUBLE"; } if (Blob.class == fieldType) { return "BLOB"; } return "TEXT"; } // 合并Field數(shù)組并去重,并實(shí)現(xiàn)過(guò)濾掉非Column字段,和實(shí)現(xiàn)Id放在首字段位置功能 public static List<Field> joinFields(Field[] fields1, Field[] fields2) { Map<String, Field> map = new LinkedHashMap<String, Field>(); for (Field field : fields1) { // 過(guò)濾掉非Column定義的字段 if (!field.isAnnotationPresent(Column.class)) { continue; } Column column = (Column) field.getAnnotation(Column.class); map.put(column.name(), field); } for (Field field : fields2) { // 過(guò)濾掉非Column定義的字段 if (!field.isAnnotationPresent(Column.class)) { continue; } Column column = (Column) field.getAnnotation(Column.class); if (!map.containsKey(column.name())) { map.put(column.name(), field); } } List<Field> list = new ArrayList<Field>(); for (String key : map.keySet()) { Field tempField = map.get(key); // 如果是Id則放在首位置. if (tempField.isAnnotationPresent(Id.class)) { list.add(0, tempField); } else { list.add(tempField); } } return list; }
}</span>
MyDBHelper.java
[java] view plaincopy
<span style="font-size:18px;">package com.tgb.lk.ahibernate.util; import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; public class MyDBHelper extends SQLiteOpenHelper { private Class<?>[] modelClasses; public MyDBHelper(Context context, String databaseName, SQLiteDatabase.CursorFactory factory, int databaseVersion, Class<?>[] modelClasses) { super(context, databaseName, factory, databaseVersion); this.modelClasses = modelClasses; } public void onCreate(SQLiteDatabase db) { TableHelper.createTablesByClasses(db, this.modelClasses); } public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { TableHelper.dropTablesByClasses(db, this.modelClasses); onCreate(db); }
}</span>
(三)接口和實(shí)現(xiàn):
BaseDao.java[java] view plaincopy
<span style="font-size:18px;">package com.tgb.lk.ahibernate.dao; import java.util.List;
import java.util.Map; import android.database.sqlite.SQLiteOpenHelper; public interface BaseDao<T> { public SQLiteOpenHelper getDbHelper(); public abstract long insert(T entity); public abstract void delete(int id); public abstract void delete(Integer... ids); public abstract void update(T entity); public abstract T get(int id); public abstract List<T> rawQuery(String sql, String[] selectionArgs); public abstract List<T> find(); public abstract List<T> find(String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit); public abstract boolean isExist(String sql, String[] selectionArgs); /** * 將查詢的結(jié)果保存為名值對(duì)map. * * @param sql * 查詢sql * @param selectionArgs * 參數(shù)值 * @return 返回的Map中的key全部是小寫形式. */ public List<Map<String, String>> query2MapList(String sql, String[] selectionArgs); /** * 封裝執(zhí)行sql代碼. * @param sql * @param selectionArgs */ public void execSql(String sql, Object[] selectionArgs); }</span> BaseDaoImpl.java
[java] view plaincopy
<span style="font-size:18px;">package com.tgb.lk.ahibernate.dao.impl; import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.lang.reflect.Field;
import java.sql.Blob;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import com.tgb.lk.ahibernate.annotation.Column;
import com.tgb.lk.ahibernate.annotation.Id;
import com.tgb.lk.ahibernate.annotation.Table;
import com.tgb.lk.ahibernate.dao.BaseDao;
import com.tgb.lk.ahibernate.util.TableHelper; /** * AHibernate概要 <br/> * (一)支持功能: 1.自動(dòng)建表,支持屬性來(lái)自繼承類:可根據(jù)注解自動(dòng)完成建表,并且對(duì)于繼承類中的注解字段也支持自動(dòng)建表. 2.自動(dòng)支持增刪改 * ,增改支持對(duì)象化操作:增刪改是數(shù)據(jù)庫(kù)操作的最基本單元,不用重復(fù)寫這些增刪改的代碼,并且添加和更新支持類似于hibernate中的對(duì)象化操作. * 3.查詢方式靈活:支持android框架提供的方式,也支持原生sql方式. * 4.查詢結(jié)果對(duì)象化:對(duì)于查詢結(jié)果可自動(dòng)包裝為實(shí)體對(duì)象,類似于hibernate框架. * 5.查詢結(jié)果靈活:查詢結(jié)果支持對(duì)象化,也支持結(jié)果為L(zhǎng)ist<Map<String,String>>形式,這個(gè)方法在實(shí)際項(xiàng)目中很實(shí)用,且效率更好些. * 6.日志較詳細(xì):因?yàn)閍ndroid開(kāi)發(fā)不支持熱部署調(diào)試,運(yùn)行報(bào)錯(cuò)時(shí)可根據(jù)日志來(lái)定位錯(cuò)誤,這樣可以減少運(yùn)行Android的次數(shù). <br/> * (二)不足之處: <br/> * 1.id暫時(shí)只支持int類型,不支持uuid,在sqlite中不建議用uuid. * 2.現(xiàn)在每個(gè)方法都自己開(kāi)啟和關(guān)閉事務(wù),暫時(shí)還不支持在一個(gè)事務(wù)中做多個(gè)操作然后統(tǒng)一提交事務(wù). <br/> * (三)作者寄語(yǔ):<br/> * 昔日有JavaScript借Java發(fā)展,今日也希望AHibernate借Hibernate之名發(fā)展. * 希望這個(gè)項(xiàng)目以后會(huì)成為開(kāi)源社區(qū)的重要一員,更希望這個(gè)項(xiàng)目能給所有Android開(kāi)發(fā)者帶便利. * 歡迎訪問(wèn)我的博客:http://blog.csdn.net/lk_blog, * 這里有這個(gè)框架的使用范例和源碼,希望朋友們多多交流完善這個(gè)框架,共同推動(dòng)中國(guó)開(kāi)源事業(yè)的發(fā)展,AHibernate期待與您共創(chuàng)美好未來(lái)!!! */
public class BaseDaoImpl<T> implements BaseDao<T> { private String TAG = "AHibernate"; private SQLiteOpenHelper dbHelper; private String tableName; private String idColumn; private Class<T> clazz; private List<Field> allFields; public BaseDaoImpl(SQLiteOpenHelper dbHelper) { this.dbHelper = dbHelper; this.clazz = ((Class<T>) ((java.lang.reflect.ParameterizedType) super .getClass().getGenericSuperclass()).getActualTypeArguments()[0]); if (this.clazz.isAnnotationPresent(Table.class)) { Table table = (Table) this.clazz.getAnnotation(Table.class); this.tableName = table.name(); } // 加載所有字段 this.allFields = TableHelper.joinFields(this.clazz.getDeclaredFields(), this.clazz.getSuperclass().getDeclaredFields()); // 找到主鍵 for (Field field : this.allFields) { if (field.isAnnotationPresent(Id.class)) { Column column = (Column) field.getAnnotation(Column.class); this.idColumn = column.name(); break; } } Log.d(TAG, "clazz:" + this.clazz + " tableName:" + this.tableName + " idColumn:" + this.idColumn); } public SQLiteOpenHelper getDbHelper() { return dbHelper; } public T get(int id) { String selection = this.idColumn + " = ?"; String[] selectionArgs = { Integer.toString(id) }; Log.d(TAG, "[get]: select * from " + this.tableName + " where " + this.idColumn + " = '" + id + "'"); List<T> list = find(null, selection, selectionArgs, null, null, null, null); if ((list != null) && (list.size() > 0)) { return (T) list.get(0); } return null; } public List<T> rawQuery(String sql, String[] selectionArgs) { Log.d(TAG, "[rawQuery]: " + sql); List<T> list = new ArrayList<T>(); SQLiteDatabase db = null; Cursor cursor = null; try { db = this.dbHelper.getReadableDatabase(); cursor = db.rawQuery(sql, selectionArgs); getListFromCursor(list, cursor); } catch (Exception e) { Log.e(this.TAG, "[rawQuery] from DB Exception."); e.printStackTrace(); } finally { if (cursor != null) { cursor.close(); } if (db != null) { db.close(); } } return list; } public boolean isExist(String sql, String[] selectionArgs) { Log.d(TAG, "[isExist]: " + sql); SQLiteDatabase db = null; Cursor cursor = null; try { db = this.dbHelper.getReadableDatabase(); cursor = db.rawQuery(sql, selectionArgs); if (cursor.getCount() > 0) { return true; } } catch (Exception e) { Log.e(this.TAG, "[isExist] from DB Exception."); e.printStackTrace(); } finally { if (cursor != null) { cursor.close(); } if (db != null) { db.close(); } } return false; } public List<T> find() { return find(null, null, null, null, null, null, null); } public List<T> find(String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit) { Log.d(TAG, "[find]"); List<T> list = new ArrayList<T>(); SQLiteDatabase db = null; Cursor cursor = null; try { db = this.dbHelper.getReadableDatabase(); cursor = db.query(this.tableName, columns, selection, selectionArgs, groupBy, having, orderBy, limit); getListFromCursor(list, cursor); } catch (Exception e) { Log.e(this.TAG, "[find] from DB Exception"); e.printStackTrace(); } finally { if (cursor != null) { cursor.close(); } if (db != null) { db.close(); } } return list; } private void getListFromCursor(List<T> list, Cursor cursor) throws IllegalAccessException, InstantiationException { while (cursor.moveToNext()) { T entity = this.clazz.newInstance(); for (Field field : this.allFields) { Column column = null; if (field.isAnnotationPresent(Column.class)) { column = (Column) field.getAnnotation(Column.class); field.setAccessible(true); Class<?> fieldType = field.getType(); int c = cursor.getColumnIndex(column.name()); if (c < 0) { continue; // 如果不存則循環(huán)下個(gè)屬性值 } else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) { field.set(entity, cursor.getInt(c)); } else if (String.class == fieldType) { field.set(entity, cursor.getString(c)); } else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) { field.set(entity, Long.valueOf(cursor.getLong(c))); } else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) { field.set(entity, Float.valueOf(cursor.getFloat(c))); } else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) { field.set(entity, Short.valueOf(cursor.getShort(c))); } else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) { field.set(entity, Double.valueOf(cursor.getDouble(c))); } else if (Blob.class == fieldType) { field.set(entity, cursor.getBlob(c)); } else if (Character.TYPE == fieldType) { String fieldValue = cursor.getString(c); if ((fieldValue != null) && (fieldValue.length() > 0)) { field.set(entity, Character.valueOf(fieldValue .charAt(0))); } } } } list.add((T) entity); } } public long insert(T entity) { Log.d(TAG, "[insert]: inset into " + this.tableName + " " + entity.toString()); SQLiteDatabase db = null; try { db = this.dbHelper.getWritableDatabase(); ContentValues cv = new ContentValues(); setContentValues(entity, cv, "create"); long row = db.insert(this.tableName, null, cv); return row; } catch (Exception e) { Log.d(this.TAG, "[insert] into DB Exception."); e.printStackTrace(); } finally { if (db != null) { db.close(); } } return 0L; } public void delete(int id) { SQLiteDatabase db = this.dbHelper.getWritableDatabase(); String where = this.idColumn + " = ?"; String[] whereValue = { Integer.toString(id) }; Log.d(TAG, "[delete]: delelte from " + this.tableName + " where " + where.replace("?", String.valueOf(id))); db.delete(this.tableName, where, whereValue); db.close(); } public void delete(Integer... ids) { if (ids.length > 0) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < ids.length; i++) { sb.append('?').append(','); } sb.deleteCharAt(sb.length() - 1); SQLiteDatabase db = this.dbHelper.getWritableDatabase(); String sql = "delete from " + this.tableName + " where " + this.idColumn + " in (" + sb + ")"; Log.d(TAG, "[delete]: " + sql); db.execSQL(sql, (Object[]) ids); db.close(); } } public void update(T entity) { SQLiteDatabase db = null; try { db = this.dbHelper.getWritableDatabase(); ContentValues cv = new ContentValues(); setContentValues(entity, cv, "update"); String where = this.idColumn + " = ?"; int id = Integer.parseInt(cv.get(this.idColumn).toString()); cv.remove(this.idColumn); Log.d(TAG, "[update]: update " + this.tableName + " where " + where.replace("?", String.valueOf(id))); String[] whereValue = { Integer.toString(id) }; db.update(this.tableName, cv, where, whereValue); } catch (Exception e) { Log.d(this.TAG, "[update] DB Exception."); e.printStackTrace(); } finally { if (db != null) db.close(); } } private void setContentValues(T entity, ContentValues cv, String type) throws IllegalAccessException { for (Field field : this.allFields) { if (!field.isAnnotationPresent(Column.class)) { continue; } Column column = (Column) field.getAnnotation(Column.class); field.setAccessible(true); Object fieldValue = field.get(entity); if (fieldValue == null) continue; if (("create".equals(type)) && (field.isAnnotationPresent(Id.class))) { continue; } cv.put(column.name(), fieldValue.toString()); } } /** * 將查詢的結(jié)果保存為名值對(duì)map. * * @param sql * 查詢sql * @param selectionArgs * 參數(shù)值 * @return 返回的Map中的key全部是小寫形式. */ public List<Map<String, String>> query2MapList(String sql, String[] selectionArgs) { Log.d(TAG, "[query2MapList]: " + sql); SQLiteDatabase db = null; Cursor cursor = null; List<Map<String, String>> retList = new ArrayList<Map<String, String>>(); try { db = this.dbHelper.getReadableDatabase(); cursor = db.rawQuery(sql, selectionArgs); while (cursor.moveToNext()) { Map<String, String> map = new HashMap<String, String>(); for (String columnName : cursor.getColumnNames()) { map.put(columnName.toLowerCase(), cursor.getString(cursor .getColumnIndex(columnName))); } retList.add(map); } } catch (Exception e) { Log.e(TAG, "[query2MapList] from DB exception"); e.printStackTrace(); } finally { if (cursor != null) { cursor.close(); } if (db != null) { db.close(); } } return retList; } /** * 封裝執(zhí)行sql代碼. * * @param sql * @param selectionArgs */ public void execSql(String sql, Object[] selectionArgs) { SQLiteDatabase db = null; Log.d(TAG, "[execSql]: " + sql); try { db = this.dbHelper.getWritableDatabase(); if (selectionArgs == null) { db.execSQL(sql); } else { db.execSQL(sql, selectionArgs); } } catch (Exception e) { Log.e(TAG, "[execSql] DB exception."); e.printStackTrace(); } finally { if (db != null) { db.close(); } } }
}</span>
轉(zhuǎn)載于:https://www.cnblogs.com/zlja/archive/2012/04/13/2446561.html
總結(jié)
以上是生活随笔為你收集整理的Android sqlite数据库操作通用框架AHibernate(二)源码-用于交流的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: php后台框架整理集锦
- 下一篇: 30天自制操作系统——Day8实验报告