日常搬砖sqlite增改查另类写法

922 阅读3分钟

前言

啊哈,今天又更新了。接上一篇日常搬砖sqlite可用类型与存储类型

顺便推一下日常搬砖sqlite目录

之前又一篇博客提到了json 对象不仅仅可以通过对象class 解析,也可以解析成map.巧合的是sqlite 添加和更新需要的ContentValues 也是一个类似于map的结构。既然object 与map互转,同理可以解决 object可以和ContentValues 互相转化,是吧。还有一个点 cursor.getType(cursor.getColumnIndex(key)) 可以获取到值的type,所以开整。先总结下可能需要的逻辑。


  • ContentValues 也是一个类似于map的结构。
  • 逻辑上object可以和ContentValues 互相转化
  • cursor.getType(cursor.getColumnIndex(key)) 可以获取到值的type。
  • 通过反射可以获取到对应字段设定的type
  • Cursor 获取到的type 包含 FIELD_TYPE_NULL,FIELD_TYPE_INTEGER,FIELD_TYPE_FLOAT,FIELD_TYPE_STRING,FIELD_TYPE_BLOB(ps:不要问我从哪里看到的,点开对应的class 都有)
  • ContentValues 支持存放主要类型:String,Byte,Short,Integer,Long,Float,Double,Boolean,byte[]等。(ps:不要问我从哪里看到的,点开对应的class 都有)

正文

通过反射拿到所以的Field

/**
 * 获取所有的内容,解决父类中参数获取不到的bug
 * @param object
 * @return
 */
private static Field[] getAllFieldsByObject(Object object){
    Class clazz = object.getClass();
    List<Field> fieldList = new ArrayList<>();
    while (clazz != null){
        fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
        clazz = clazz.getSuperclass();
    }
    Field[] fields = new Field[fieldList.size()];
    fieldList.toArray(fields);
    return fields;
}

/**
     * 获取对象中所有可用字段。
     * @param clazz
     * @return
     */
    private static Field[] getAllFieldsByClass(Class clazz){
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null){
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }

object转ContentValues

/**
 * 将对象转为 ContentValues
 * @param object
 * @return
 */
public static ContentValues entityToContentValues(Object object) {
    ContentValues map=new ContentValues();
    for (Field field : getAllFieldsByObject(object)){
        try {
            boolean flag = field.isAccessible();
            field.setAccessible(true);
            Object o = field.get(object);
            if (o!=null){
                if (o instanceof Integer){
                    map.put(field.getName(),(Integer) o);
                }
                if (o instanceof String){
                    map.put(field.getName(),(String) o);
                }
                if (o instanceof Double){
                    map.put(field.getName(),(Double) o);
                }
                if (o instanceof Float){
                    map.put(field.getName(),(Float) o);
                }
                if (o instanceof Byte){
                    map.put(field.getName(),(Byte) o);
                }
                if (o instanceof Short){
                    map.put(field.getName(),(Short) o);
                }
                if (o instanceof Long){
                    map.put(field.getName(),(Long) o);
                }if (o instanceof Boolean){
                    map.put(field.getName(),(Boolean) o);
                }
                if (o instanceof  byte[]){
                    map.put(field.getName(),( byte[]) o);
                }

                field.setAccessible(flag);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return map;
}

这个可能有些字段没有转化完,但是一应该是完整的。

从cursor 中获取ContentValues

因为corsor 定义了4种类型。大概只能这么转化

ContentValues values = new ContentValues();
for (String key : cursor.getColumnNames()) {
    int index = cursor.getColumnIndex(key);
    int type = cursor.getType(index);
    if (type == Cursor.FIELD_TYPE_STRING) {
        //按照string的取法。
        values.put(key, cursor.getString(index));
    } else if (type == Cursor.FIELD_TYPE_BLOB) {
        values.put(key, cursor.getBlob(index));
    } else if (type == Cursor.FIELD_TYPE_FLOAT) {
        values.put(key, cursor.getFloat(index));
    } else if (type == Cursor.FIELD_TYPE_INTEGER) {
        values.put(key, cursor.getInt(index));
    } else {
        //表示是空就不取。
    }
}

从cursor获取class 对象

这个就需要反射获取到key了。

/**
 * 将cursor 中的数据根据 传入的class 赋值到里面。
 * @param cursor
 * @param entity
 * @param <T>
 * @return
 */
public static <T> T getObjectByCursor(Cursor cursor,Class<T> entity){
        T t = null;
        try {
            t = entity.newInstance();
            for(Field field : getAllFieldsByClass(entity)) {
                Class<?> type = field.getType();
                boolean flag = field.isAccessible();
                field.setAccessible(true);
                if (type == byte [] .class||type== Byte [] .class){
                    field.set(t, cursor.getBlob(cursor.getColumnIndex(field.getName())));
                }
                if (type==byte.class||type==Byte.class){
                    field.set(t,cursor.getInt(cursor.getColumnIndex(field.getName())));
                }
                if (type == String.class){
                    field.set(t, cursor.getString(cursor.getColumnIndex(field.getName())));
                }
                if (type == short.class||type==Short.class){
                    field.set(t, cursor.getShort(cursor.getColumnIndex(field.getName())));
                }
                if (type == int.class||type==Integer.class){
                    field.set(t, cursor.getInt(cursor.getColumnIndex(field.getName())));
                }
                if (type == long.class||type==Long.class){
                    field.set(t, cursor.getLong(cursor.getColumnIndex(field.getName())));
                }
                if (type == float.class||type==Float.class){
                    field.set(t, cursor.getFloat(cursor.getColumnIndex(field.getName())));
                }
                if (type == double.class||type==Double.class){
                    field.set(t, cursor.getDouble(cursor.getColumnIndex(field.getName())));
                }
                if (type==boolean.class||type==Boolean.class){
                    field.set(t,cursor.getInt(cursor.getColumnIndex(field.getName()))==1?true:false);
                }

                field.setAccessible(flag);
            }
            return t;
        } catch (InstantiationException e) {
            LogUtils.e(e);
        } catch (IllegalAccessException e) {
            LogUtils.e(e);
        }
        return t;
    }

从cursor 中获取列表数据

这个主要是基于上面方法。

/**
 *Cursor 获取列表数据
 * @param cursor
 * @param c
 * @return
 */
public static  <T> List<T> getObjectsByCursor(Cursor cursor,Class<T> c){
    List<T>  objects=new ArrayList<>();
    while (cursor.moveToNext()) {
        objects.add(getObjectByCursor(cursor,c));
    }
    cursor.close();
    return objects;
}

说一个点,虽然JAVA 有自动回收机制,但是 cursor.close(); 还是可以写的。

sqlite 增加 查找 更新

增加和更新 都是通过ContentValues操作的,那么我们传入设定的正确约束对象转化为ContentValues就可以了。

而查找方面,上列仅仅用于查找多个字段的数据,你说只需要查一个字段一个参数,直接通过 cursor 获取就好了,不用这么麻烦吧,靓仔。

cursor.getColumnNames() 这个调调可以查看当前包含的字段。很重要。

结束

谢谢光临,若觉得还行麻烦点一下赞,若觉得写得垃圾,欢迎批评指正。笔者知道自己文笔和表达能力很弱,如果您可以提供点宝贵的意见不胜感激。谢谢。

今天也可以是元气满满的一天哦。