Litepal 使用原生SQL语句进行复杂查询

Litepal 使用原生Sql进行复杂查询的反射工具类

问题:

        这几天因为课程原因,开始是Android开发的学习,在学习本地持久化层框架Litepal时,赞叹它使数据库操作如此简单优雅,但是今天,本人在项目作业上有一个多条件组合的查询,就是类似 下面这样的组合条件

where 
(senderNetId = ? AND receiverNetId = ?) 
OR 
(receiverNetId = ? AND senderNetId = ?) 
order by createtime desc 
limit 20

         看了官方文档和一些博客,并没有找到直接可以用的方式,所以就只能用 Litepal 的 findBySql(”sql statement“),这个方法会返回一个 Cursor cursor 的对象,这个对象就是一个从数据库中查询出来的结果集,就好比是之前做Web开发,原生数据库JDBC操作,返回的结果集 ResultSet 是一回事。

         首先就想到了能否做到对结果集进行通用的处理呢?结合数据库ORM这些框架,不管是 Litepal 还是Hibernate、Mybatis。反射,这是可以解决软件通用性的好东西,同时也是各种框架的很多底层技术的支撑。

         这里,便想着通过反射,对数据集进行通用性的处理转成 List 形式,写一个工具类,开发人员不需要针对结果集进行重复性很大的编写工作。代码还有很多未完善优化的地方,仅提供一些思路。

用例:

public ArrayList findNearlyMessage(int friendNetId,int ownerNetId){

        String fnId=String.valueOf(friendNetId);
        String onId=String.valueOf(ownerNetId);

        //Litepal 的 findBySQL 方法
        Cursor cursor=
                LitePal.findBySQL(

                  "select * from message 
                    where 
                    (senderNetId = ? AND receiverNetId = ?) 
                    OR 
                    (receiverNetId = ? AND senderNetId = ?) 
                    order by createtime desc 
                    limit 20",
                        
                    onId,fnId,
                    fnId,onId);
        
        //调用工具类对cursor进行提取数据封装处理

        ArrayList messages=DBUtil.cursorToList(cursor,Message.class);

        if (messages.size()==0||messages==null){
            return new ArrayList();
        }
        return messages;
    }

工具类 DBUtil 的 cursorToList 方法

public static ArrayList cursorToList(Cursor cursor,Class objClass) {
        try {
            ArrayList objList=new ArrayList();
            //获取全部字段名
            Field[] fields=objClass.getDeclaredFields();
            //通过fieldName获取指定数据
            while (cursor.moveToNext()){
                Object newObj=objClass.newInstance();
                for (Field field : fields){
                    field.setAccessible(true);
                    String colName=field.getName().toLowerCase();
                    Class fileType=field.getType();
                    int valueIndex=cursor.getColumnIndex(colName);
                    Object value=null;
                    
                    //
                    //根据字段类型判断调用哪个方法/String/Int/Long/boolean
                    //这一块可以进行优化,做到更通用性
                    switch (fileType.getSimpleName()){
                        case "String":
                            value=cursor.getString(valueIndex);
                            break;
                        case "int":
                            value=cursor.getInt(valueIndex);
                            break;
                        case "long":
                            value=cursor.getLong(valueIndex);
                            break;
                        case "boolean":
                            int dbVal=cursor.getInt(valueIndex);
                            value=true;
                            if (dbVal == 0){
                                value=false;
                            }
                    }
                    field.set(newObj,value);
                }
                objList.add(newObj);
            }
            return objList;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

 

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