andbase中sqlite的orm框架litepal支持Bitmap存储

来源:互联网 发布:网络名字大全女孩四字 编辑:程序博客网 时间:2024/04/30 11:57

        最近在学习andbase开发框架,该框架实现了许多android开发中常用的功能,为我们针对android应用的开发提供了很大的便利,在使用的过程中,由于项目的需求,需要在APP中存储图片信息,LZ比较懒没有保存文件信息,而是想直接在sqlite数据库中保存Bitmap类型的数据,但是发现这个orm框架不支持这样的操作。于是下载源码,修改一番,终于修改成功。

       下面是lz修改源码的整个过程:

       (1)在github中下载andbase源码,下载地址:点击打开链接 ,也可以直接在:点击打开链接

       (2)将下载的andbase源码导入到eclipse中(lz比较习惯使用),如下图所示,可以看到andbase的源码,其中红框标注的部分为数据库orm框架的实现源码(当然有兴趣的童鞋可以好好研究一下其他部门的源码,写这个框架的作者是一个很厉害的大牛,膜拜)。


   (3)在使用andbase的orm框架的时候,我们操作数据库基本都是使用AbDBDaoImpl这个实现类的方法,所以我们找到这个类的源码,在插入和查询方法时,增加对Bitmap类型数据的支持,就应该可以实现我们的目的了,及修改andbase源码增加数据库对bitmap类型数据的支持。


    (4)首先查找插入方法的实现,根据对代码的追踪过程中,可以查找到如下代码,其中有一个重要的方法时setContentValues,这个方法是初始化插入sql语句以及ContentValues对象。下面我们查看方法setContentValues方法的实现细节。

/** * 描述:插入实体. * @param entity the entity * @param flag the flag * @return the long * @see com.ab.db.orm.dao.AbDBDao#insert(java.lang.Object, boolean) */@Overridepublic long insert(T entity, boolean flag) {String sql = null;long row = 0L;try {lock.lock();ContentValues cv = new ContentValues();if (flag) {// id自增sql = setContentValues(entity, cv, TYPE_INCREMENT,METHOD_INSERT);} else {// id需指定sql = setContentValues(entity, cv, TYPE_NOT_INCREMENT,METHOD_INSERT);}Log.d(TAG, "[insert]: insert into " + this.tableName + " " + sql);Log.d("abc", sql);row = db.insert(this.tableName, null, cv);//获取关联域的操作类型和关系类型String foreignKey = null;String type = null;String action = null;

    (5)查看setContentValues方法的实现细节,我们可以看到其中有对Date类型数据的处理逻辑,所以我们只需要在这其中添加对Bitmap类型的处理,即可实现对Bitmap类型数据的插入操作。


/** * 设置这个ContentValues. * * @param entity 映射实体 * @param cv the cv * @param type id类的类型,是否自增 * @param method 预执行的操作 * @return sql的字符串 * @throws IllegalAccessException the illegal access exception */private String setContentValues(T entity, ContentValues cv, int type,int method) throws IllegalAccessException {StringBuffer strField = new StringBuffer("(");StringBuffer strValue = new StringBuffer(" values(");StringBuffer strUpdate = new StringBuffer(" ");// 加载所有字段List<Field> allFields = AbTableHelper.joinFields(entity.getClass().getDeclaredFields(),entity.getClass().getSuperclass().getDeclaredFields());for (Field field : 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 ((type == TYPE_INCREMENT) && (field.isAnnotationPresent(Id.class))) {continue;}// 处理java.util.Date类型,updateif (Date.class == field.getType()) {// 2012-06-10cv.put(column.name(), ((Date) fieldValue).getTime());continue;}String value = String.valueOf(fieldValue);cv.put(column.name(), value);if (method == METHOD_INSERT) {strField.append(column.name()).append(",");strValue.append("'").append(value).append("',");} else {strUpdate.append(column.name()).append("=").append("'").append(value).append("',");}}if (method == METHOD_INSERT) {strField.deleteCharAt(strField.length() - 1).append(")");strValue.deleteCharAt(strValue.length() - 1).append(")");return strField.toString() + strValue.toString();} else {return strUpdate.deleteCharAt(strUpdate.length() - 1).append(" ").toString();}}

    在对Date类型处理逻辑的后面添加 添加对Bitmap类型数据的处理操作。

   

<span style="white-space:pre"></span>if (Bitmap.class == field.getType()) {                Bitmap bitmap = (Bitmap) fieldValue;                                ByteArrayOutputStream baos = new ByteArrayOutputStream();                bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);                                cv.put(column.name(), baos.toByteArray());                continue;            }  

   现在andbase的orm框架的插入操作已经可以支持Bitmap类型的数据了。别高兴的太早,现在我们只是支持对btimap类型数据的插入操作,查询时还是不支持的,下面我们需要修改查询时的源码,使其支持对Bitmap对象的支持。

  

(6)修改查询方法源码。一般数据查询的时候都是使用的queryList()方法,通过对源代码的追踪我们可以查看到getListFromCursor方法里面含有对反射类型数据的处理逻辑,下面的操作就简单了,添加对bitmap数据的支持就好了(注意53行及以后的处理)。

/** * 从游标中获得映射对象列表. * * @param list 返回的映射对象列表 * @param cursor 当前游标 * @return the list from cursor * @throws IllegalAccessException the illegal access exception * @throws InstantiationException the instantiation exception */private void getListFromCursor(Class<?> clazz,List<T> list, Cursor cursor)throws IllegalAccessException, InstantiationException {while (cursor.moveToNext()) {Object entity = clazz.newInstance();// 加载所有字段List<Field> allFields = AbTableHelper.joinFields(entity.getClass().getDeclaredFields(),entity.getClass().getSuperclass().getDeclaredFields());for (Field field : 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; // 如果不存则循环下个属性值} 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 (Date.class == fieldType) {// 处理java.util.Date类型,update2012-06-10Date date = new Date();date.setTime(cursor.getLong(c));field.set(entity, date);} else if (Blob.class == fieldType) {field.set(entity, cursor.getBlob(c));} else if (Bitmap.class == fieldType) {byte[] byt = cursor.getBlob(c);field.set(entity, BitmapFactory.decodeByteArray(byt, 0, byt.length));} else if (Character.TYPE == fieldType) {String fieldValue = cursor.getString(c);if ((fieldValue != null) && (fieldValue.length() > 0)) {field.set(entity, Character.valueOf(fieldValue.charAt(0)));}}else if ((Boolean.TYPE == fieldType) || (Boolean.class == fieldType)) {                        String temp = cursor.getString(c);                        if ("true".equals(temp) || "1".equals(temp)){                            field.set(entity, true);                        }else{                            field.set(entity, false);                        }                    }}}list.add((T) entity);}}

 (7)重新编译,导出jar包,下面我们就可以使用我们修改之后的andbase框架存储biamap类型的数据啦。


 (8)下面为使用重新编译之后的andbase jar文件插入bitmap数据的例子。


  1)定义orm映射对象



  2)定义Dao类

 


  3)定义DBInsideHelper类。



  4)Activity的实现。



   5)好了,运行一下,看一下我们的找事效果:

 



3 0