xUtils 的一些简单使用我就不重复了,对xutils不熟的同学可以直接到github看下简介

xUtils 3.0官网


原来我一直用的是xutils 2.0的数据库,操作是很简单,但是效率好像不是很高。而xUtils 3.0 的数据库,拥有更加灵活的ORM, 和greenDao一致的性能。在使用过程中,我也遇到了不少坑,不过大多数是因为自己对api不熟悉造成的。这两天在使用xUtils 3.0数据库进行update的时候遇到了点问题,于是花了点时间看了下这一部分的源码,跟大家分享一下。我们都知道在进行更新的时候只需要调用DbManger的update方法,let‘s go 跟上代码的脚步。


首先我们进入update方法

void update(Object entity, String... updateColumnNames) throws DbException;

第一个参数是你要更新的对象,第二个可变参数是要更新的字段,如果不传的话默认更新所有字段(后面会说明)。


现在我们跟到实现类里面看下方法处理

@Override
    public void update(Object entity, String... updateColumnNames) throws DbException {
        try {
            beginTransaction();

            if (entity instanceof List) {
                List<?> entities = (List<?>) entity;
                if (entities.isEmpty()) return;
                TableEntity<?> table = this.getTable(entities.get(0).getClass());
                if (!table.tableIsExist()) return;
                for (Object item : entities) {
                    execNonQuery(SqlInfoBuilder.buildUpdateSqlInfo(table, item, updateColumnNames));
                }
            } else {
                TableEntity<?> table = this.getTable(entity.getClass());
                if (!table.tableIsExist()) return;
                execNonQuery(SqlInfoBuilder.buildUpdateSqlInfo(table, entity, updateColumnNames));
            }

            setTransactionSuccessful();
        } finally {
            endTransaction();
        }
    }

从上面我们可以看到代码内部,对传的对象进行了判断如果是集合就循环遍历更新,如果是相应实体类就直接更新。其实这不是重点,我们要看的是如何去更新,so 我们再跟到SqlInfoBuilder.buildUpdateSqlInfo(table, entity, updateColumnNames)里面去看一下(这里面是大致就是sql语句的拼接了)

public static SqlInfo buildUpdateSqlInfo(TableEntity<?> table, Object entity, String... updateColumnNames) throws DbException {

        List<KeyValue> keyValueList = entity2KeyValueList(table, entity);//这一句应该是根据实体类创建了一个装载键值对对象的list,后面会用到
        if (keyValueList.size() == 0) return null;
        //下面是把要更新的字段放到一个hashset中,假如我们不传更新字段,即updateColumnNameSet=null;后面会根据它去判断,拼接要更新的字段 
        HashSet<String> updateColumnNameSet = null;
        if (updateColumnNames != null && updateColumnNames.length > 0) {
            updateColumnNameSet = new HashSet<String>(updateColumnNames.length);
            Collections.addAll(updateColumnNameSet, updateColumnNames);
        }
        //获取id 更新条件的判定条件就是它,后面很明显
        ColumnEntity id = table.getId();
        Object idValue = id.getColumnValue(entity);

        if (idValue == null) {
            throw new DbException("this entity[" + table.getEntityType() + "]'s id value is null");
        }
        //开始sql语句的拼接
        SqlInfo result = new SqlInfo();
        StringBuilder builder = new StringBuilder("UPDATE ");
        builder.append("\"").append(table.getName()).append("\"");
        builder.append(" SET ");
        for (KeyValue kv : keyValueList) { 
             //当updateColumnNameSet为null时直接拼接实体类所有的键值对 不为null则只拼接传过来的字段
            if (updateColumnNameSet == null || updateColumnNameSet.contains(kv.key)) {
                builder.append("\"").append(kv.key).append("\"").append("=?,");
                result.addBindArg(kv);
            }
        }
        builder.deleteCharAt(builder.length() - 1);
        builder.append(" WHERE ").append(WhereBuilder.b(id.getName(), "=", idValue));

        result.setSql(builder.toString());
        return result;
    }

这一部分代码并不多,我们一点点看,主要是看逻辑,千万不要纠结一些小细节。上面我也写了一部分注释,希望能帮到大家。


Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐