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

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

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

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

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

andbase中sqlite的orm框架litepal支持Bitmap存储_第1张图片

   (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)
	 */
	@Override
	public 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类型,update
			if (Date.class == field.getType()) {
				// 2012-06-10
				cv.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-10
						Date 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映射对象

andbase中sqlite的orm框架litepal支持Bitmap存储_第2张图片


  2)定义Dao类

 andbase中sqlite的orm框架litepal支持Bitmap存储_第3张图片


  3)定义DBInsideHelper类。

andbase中sqlite的orm框架litepal支持Bitmap存储_第4张图片


  4)Activity的实现。

andbase中sqlite的orm框架litepal支持Bitmap存储_第5张图片andbase中sqlite的orm框架litepal支持Bitmap存储_第6张图片


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

 andbase中sqlite的orm框架litepal支持Bitmap存储_第7张图片



你可能感兴趣的:(sqlite,android应用)