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

前端之家收集整理的这篇文章主要介绍了andbase中sqlite的orm框架litepal支持Bitmap存储前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

最近在学习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)
	 */
	@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,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,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)好了,运行一下,看一下我们的找事效果

原文链接:https://www.f2er.com/sqlite/200071.html

猜你在找的Sqlite相关文章