简易ORM Sqlite框架 一 查询

上一篇我们讲了如何存储数据,这一篇,当然是查询数据了,这是最基本的操作了,如何将一个cursor表映射成为一个model呢,我们还是用反射来。

/**
     * 获取模型
     * @param cursor
     * @param classZ
     * @param <T>
     * @return
     */
    public  <T> List<T> getModel(final Cursor cursor,Class<T> classZ){

        int resultCounts = cursor.getCount();

        if (resultCounts == 0) {
            return null;
        }

        Class <T> c = classZ;
        Field[] fields = c.getDeclaredFields();
        Method[] methods = c.getDeclaredMethods();
        List<T> list = new ArrayList<>();
        while(cursor.moveToNext()) {
           T a = getInstance(c);
            for (Field f : fields) {

                String fieldName = f.getName();

                String typeName = f.getType().getSimpleName();

                String setMethodName = "set" + fieldName;

                //找到对应的set方法
                Method method = getMethod(setMethodName, methods);
                if(null == method) continue;

                final int columnIndex = cursor.getColumnIndex(fieldName);

                final Object[] ot = {new Object()};
                Object oj = null;
                getResult(typeName, oj, new ValueTypeInterface() {
                    @Override
                    public void getValue(Integer result) {
                        ot[0] = cursor.getInt(columnIndex);
                    }

                    @Override
                    public void getValue(Boolean result) {
                        int intresult = cursor.getInt(columnIndex);
                        if(intresult == 0)
                            ot[0] = false;
                        else
                            ot[0] = true;
                    }

                    @Override
                    public void getValue(Float result) {
                        ot[0] = cursor.getFloat(columnIndex);
                    }

                    @Override
                    public void getValue(Double result) {
                        ot[0] = cursor.getDouble(columnIndex);
                    }

                    @Override
                    public void getValue(Long result) {
                        ot[0] = cursor.getLong(columnIndex);
                    }

                    @Override
                    public void getValue(String result) {
                        ot[0] = cursor.getString(columnIndex);
                    }

                    @Override
                    public void getValue(Byte result) {
                        ot[0] = cursor.getBlob(columnIndex);
                    }
                });

                try {
                    method.invoke(a, ot);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }

            }
            list.add(a);
        }

        return list;
    }

   /**
     * 通过反射去实例化相应类
     *
     * @param <T> 返回实例的泛型类型
     * @return
     */
    public static <T> T getInstance(Class clazz) {
        try {
            return (T) clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

我们传入一个cursor表和一个我们要转的model 的class实例,我们通过这个实例反射生成一个对象,然后找到每个对象的set方法,因为要通过set方法来将cursor表中的值设进model中,到了这里,我们已经能将一个cursor表所有的对象映射成为一个list对象了,我们编写我们数据库操作的查询操作DBAction的query方法实现

@Override
    public <T> List<T> query(String tableNamele, String[] selection, String[] selectionArgs, String orderBy,Class<T> classZ) {
        String[] columns = dbUtils.getTableFieldName(classZ);
        StringBuffer sb = new StringBuffer();
        if(null != selection) {
            for (String s : selection) {
                sb = sb.append(s);
            }
        }
        Cursor cursor = db.query(tableNamele,columns,sb.toString(),selectionArgs,"","",orderBy);
        List<T> list = dbUtils.<T>getModel(cursor,classZ);

        return list;
    }

我们需要传入表名,查询的条件以及model的对应的class实例,我们在这里使用泛型而不是使用Object是有好处的,因为泛型会在编译是检查类型,有什么问题我们在编译时就发现了,使用Object会不安全,并且还需要手动转换类型,很麻烦,所以要使用泛型,这样一个方法可以变得很灵活,不过也有坏处,具体好坏我就不在这里说了,然后我们UserDao的实现

 @Override
    public User get(String id) {
        daoHelp.open();
        List<User> list = daoHelp.getDao().query(USERTABLE,new String[]{"id=?"},new String[]{id},null,User.class);
        daoHelp.close();
        if(null != list && list.size() > 0)
            return list.get(0);
        else
            return null;
    }

我们通过id去查询数据库 并且取出数据,调用方式

findViewById(R.id.btnQuery).setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        User user = dao.get("15");
                        Log.i("TAG",user.toString());
                    }
                }
        );

到这里,我们的简易sqlite框架就完成了一大半,不过我们还是要自己写建表语句是不是觉得特别麻烦,为什么不能像java后台一样使用JPA直接将一个model映射成表呢?肯定可以啊,下一篇,我们加入注解,直接将model映射成一张表,先到这里了。

源码已上传github
github地址:https://github.com/jredthree/DBTest

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值