Orm,android中数据库封装(二)

介绍

这篇主要是数据库增,删的实现。其原理还是利用注解拿到变量名,然后确定对应的列名。拼装参数集合;之后用android提供的sqlite操作方法执行sql语句实现数据库的增删改查操作。

  • 项目代码地址:https://github.com/BravoLee/AndroidDb

代码部分

1. 增

  • Activity层调用,插入5条数据。

             //增 
        public void insert(View v) {
    
            for (int i = 0; i < 5; i++) {
                User user = new User();
                user.name = "alex" + i;
                user.password = "123" + i;
                userDao.insert(user);
            }
    
            Toast.makeText(this, "insert finished", Toast.LENGTH_SHORT).show();
        }
  • insert(User user)方法的实现。

        @Override
        public Long insert(T entity) {
            Map<String, String> map = getValues(entity);
            ContentValues values = getContentValues(map);
            Long result = database.insert(tableName, null, values);
            return result;
        }
    
        private Map<String, String> getValues(T entity) {
            HashMap<String, String> result = new HashMap<>();
            //准备遍历类的对象中的成员
            Iterator<Field> fieldIterator = cacheMap.values().iterator();
            while (fieldIterator.hasNext()) {
                //拿到类对象中的成员
                Field columnToField = fieldIterator.next();
                String cacheKey = null;//列名
                String cacheValue = null;//变量的值
                if (columnToField.getAnnotation(DbFlied.class).value() != null) {
                    cacheKey = columnToField.getAnnotation(DbFlied.class).value();
                } else {
                    cacheKey = columnToField.getName();
                }
    
                try {
                    if (null == columnToField.get(entity)) {
                        continue;
                    }
                    cacheValue = columnToField.get(entity).toString();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                //将列名和变量的值存起来。
                result.put(cacheKey, cacheValue);
            }
    
            return result;//返回key-value集合
        }
    
       //构造ContentValues参数
        private ContentValues getContentValues(Map<String, String> map) {
            ContentValues contentValues = new ContentValues();
            Set<String> keys = map.keySet();
            Iterator<String> iterator = keys.iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                String value = map.get(key);
                if (value != null) {
                    contentValues.put(key, value);
                }
            }
            return contentValues;
        }
  • 这样就完成了数据的插入。

  • Activity层调用,删除name为alex0的条目。
    public void delete(View v) { User user = new User();
        user.name = "alex0";
        userDao.delete(user);
        Toast.makeText(this, "delete finished", Toast.LENGTH_SHORT).show(); }
  • delete(user)方法的实现
    @Override
    public int delete(T entity) {
        Map map = getValues(entity);
        Condition condition = new Condition(map);
        int delete = database.delete(tableName, 
                        condition.getWhereClause(), condition.getWhereArgs());
        return delete;
    }
  • 其中getValues(entity)复用的是insert中的getValues,是完全相同的。而Conditions中包含了删除的参数,功能主要是根据class 来拼接语句。其代码如下:
    /** * 封装语句 */
    class Condition {
        /** * 查询条件 * name=? && password =? */
        private String whereClause;

        private String[] whereArgs;

        public Condition(Map whereClause) {
            ArrayList list = new ArrayList<>();
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("1 = 1");
            Set keys = whereClause.keySet();
            Iterator iteratorKey = keys.iterator();
            while (iteratorKey.hasNext()) {
                String key = iteratorKey.next();
                String value = whereClause.get(key);
                if (value != null) {
                    //拼装String
                    stringBuilder.append(" and " + key + " =?");
                    list.add(value);
                }
            }
            this.whereClause = stringBuilder.toString();
            this.whereArgs = list.toArray(new String[list.size()]);
        }


        public String getWhereClause() {
            return whereClause;
        }

        public String[] getWhereArgs() {
            return whereArgs;
        }
    }

  • Activity层调用,将alex1的密码改为xxxx;
    public void update(View v) {
        User where = new User();
        where.name = "alex1";
        User entity = new User();
        entity.password = "xxxx";
        userDao.update(where, entity);
        Toast.makeText(this, "update finished", Toast.LENGTH_SHORT).show();
    }
  • update(where, entity) 的实现如下:
    @Override
    public int update(T where, T entity) { Map map = getValues(where);
        Condition condition = new Condition(map);
        ContentValues contentValues = getContentValues(getValues(entity));
        int update = database.update(tableName, contentValues, condition.getWhereClause(), condition.getWhereArgs());
        return update;
    }
  • 其中 getValues ,Condition,和getContentValues的实现已经在增和删的时候已经实现了。

  • Activity层调用,将查询到的结果用log打印出来
    public void query(View v) {
        User where = new User();
        where.name = "alex2";

        List<User> query = userDao.query(where);
        Toast.makeText(this, "query finished , Number : " + query.size(), Toast.LENGTH_SHORT).show();
        for (User user : query) {
            Log.e(TAG, query.toString());
        }
    }
  • quey(where)方法的实现如下:
    @Override
    public List<T> query(T where) {
        return query(where, null, null, null);
    }

    @Override
    public List<T> query(T where, String orderBy, String startIndex, Integer limit) {
        Map<String, String> map = getValues(where);
        String limitString = null;
        if (startIndex != null && limit != null) {
            limitString = startIndex + " , " + limit;
        }
        Condition condition = new Condition(map);
        Cursor cursor = database.query(tableName, null, 
                        condition.getWhereClause(), condition.getWhereArgs(),
                         null, null, orderBy, limitString);
        List<T> result = getResult(cursor,where);
        cursor.close();
        return result;
    }
  • 查找这里,与之前的增删改有差异的地方在于我们要将查找出来的数据,创建成集合返回到调用层,向心你也看到的,这个过程应该在getResult(cursor,where);里面,具体的请看下面这段代码。
    private List getResult(Cursor cursor, T where) {
        ArrayList result = new ArrayList<>();
        T item = null;
        while (cursor.moveToNext()){
            try {
                item = (T) where.getClass().newInstance();
                //使用缓存的map key-value集合
                Iterator> iterator = cacheMap.entrySet().iterator();
                while (iterator.hasNext()){
                    Map.Entry next = iterator.next();
                    String columunName = next.getKey();
                    int columnIndex = cursor.getColumnIndex(columunName);
                    Field field = next.getValue();

                    Class type = field.getType();
                    if (columnIndex != -1){
                        //逐个判断类型,然后进行赋值。
                        if (type == String.class){
                            field.set(item,cursor.getString(columnIndex));
                        }else if (type == Double.class){
                            field.set(item,cursor.getDouble(columnIndex));
                        }else if (type == Integer.class){
                            field.set(item,cursor.getInt(columnIndex));
                        }else if (type == Long.class){
                            field.set(item,cursor.getLong(columnIndex));
                        }else if (type == byte[].class){
                            field.set(item,cursor.getBlob(columnIndex));
                        }else{
                           continue;
                        }
                    }
                }
                result.add(item);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

小结

到这里,增删改查的操作已经完了。相信你也可以看到,在MainActivity层,不再需要关心具体的sql语句的拼写,全部交给框架来实现。这样在开发起来会很方便。
如果你想了解数据库升级的相关黑科技,后续也会有更新。

你可能感兴趣的:(数据库)