XUtils 源码分析(三)--数据库操作模块
发布日期:2021-10-04 02:53:47 浏览次数:7 分类:技术文章

本文共 31429 字,大约阅读时间需要 104 分钟。

一 数据库创建

1.客户端程序:

DbUtils.DaoConfig config = new DbUtils.DaoConfig(context); 
       config.setDbName("user.db");
       mUserInforDbUtils = DbUtils.create(config);

2.DbUtils的创建函数:

public static DbUtils create(DaoConfig daoConfig) {
       return getInstance(daoConfig);
   }

3.私有静态方法获取DbUtils实例:先检查缓存,没有就去创建。

/** 
    * 获取一个DbUtils,首先检查Map是否有缓存,没有新建添加到Map中
    */
   private synchronized static DbUtils getInstance(DaoConfig daoConfig) {
       DbUtils dao = daoMap.get(daoConfig.getDbName());
       if (dao == null) {
           dao = new DbUtils(daoConfig);//生成数据库操作对象,新建数据库
           daoMap.put(daoConfig.getDbName(), dao);//存放数据库操作对象
       } else {
           dao.daoConfig = daoConfig;//更新配置
       }
       //处理数据库更新问题
       SQLiteDatabase database = dao.database;
       int oldVersion = database.getVersion();
       int newVersion = daoConfig.getDbVersion();
       if (oldVersion != newVersion) {
//版本不一致
           if (oldVersion != 0) {
               DbUpgradeListener upgradeListener = daoConfig.getDbUpgradeListener();
               if (upgradeListener != null) {
                   upgradeListener.onUpgrade(dao, oldVersion, newVersion);//用户自定义更新
               } else {
//清空旧的数据库
                   try {
                       dao.dropDb();
                   } catch (DbException e) {
                       LogUtils.e(e.getMessage(), e);
                   }
               }
           }
           database.setVersion(newVersion);
       }        return dao;
   }

3.1 私有构造方法:

private DbUtils(DaoConfig config) {
       if (config == null) {
           throw new IllegalArgumentException("daoConfig may not be null");
       }
       this.database = createDatabase(config);
       this.daoConfig = config;
   }

3.1.1 构造方法生成的数据库createDatabase(config):

 /* 
    * 新建数据库
    */
   private SQLiteDatabase createDatabase(DaoConfig config) {
       SQLiteDatabase result = null;
       String dbDir = config.getDbDir();
       if (!TextUtils.isEmpty(dbDir)) {
//数据库路径不为空
           File dir = new File(dbDir);
           if (dir.exists() || dir.mkdirs()) {
               File dbFile = new File(dbDir, config.getDbName());
               result = SQLiteDatabase.openOrCreateDatabase(dbFile, null);//生成数据库文件
           }
       } else {//生成数据库对象
           result = config.getContext().openOrCreateDatabase(config.getDbName(), 0, null);
       }
       return result;
   }

3.2清空数据库:

 /** 
    * 清空数据库
    */
   public void dropDb() throws DbException {
       Cursor cursor = execQuery("SELECT name FROM sqlite_master WHERE type='table' AND name<>'sqlite_sequence'");
//获得数据库中的所有表
       if (cursor != null) {
           try {
               while (cursor.moveToNext()) {
                   try {
                       String tableName = cursor.getString(0);
                       execNonQuery("DROP TABLE " + tableName);//清空
                       Table.remove(this, tableName);
                   } catch (Throwable e) {
                       LogUtils.e(e.getMessage(), e);
                   }
               }
           } catch (Throwable e) {
               throw new DbException(e);
           } finally {
               IOUtils.closeQuietly(cursor);
           }
       }
   }

4.客户端存储数据:

  try {
           mUserInforDbUtils.save(user); // 使用saveBindingId保存实体时会为实体的id赋值
       } catch (DbException e) {
           e.printStackTrace();
       }

4.1 save函数 mUserInforDbUtils.save(user);

   /** 
    * 数据库存储记录
    */
   public void save(Object entity) throws DbException {
       try {
           beginTransaction();//开启事务
           createTableIfNotExist(entity.getClass());//检测表是否存在,不存在就新建
           execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(this, entity));
           setTransactionSuccessful();
       } finally {
           endTransaction();
       }
   }
4.1.1 开启数据库事物管理 beginTransaction();
/** 
    * 开启事务管理
    */
   private void beginTransaction() {
       if (allowTransaction) {
//允许开启
           database.beginTransaction();
       } else {
//不允许锁定
           writeLock.lock();
           writeLocked = true;
       }
   }

4.1.2 表不存在就创建 createTableIfNotExist(entity.getClass());

 /** 
    * 不存在表就新建
    */
   public void createTableIfNotExist(Class
entityType) throws DbException {
       if (!tableIsExist(entityType)) {
//表不存在,注意表对象已存在
           SqlInfo sqlInfo = SqlInfoBuilder.buildCreateTableSqlInfo(this, entityType);//生成SQL语句对象
           execNonQuery(sqlInfo);//执行语句,建表
           String execAfterTableCreated = TableUtils.getExecAfterTableCreated(entityType);
           if (!TextUtils.isEmpty(execAfterTableCreated)) {
               execNonQuery(execAfterTableCreated);//设置表默认值
           }
       }
   }
4.1.2.1判断表是否存在 tableIsExist(entityType);
   /** 
    * 判断表是否存在
    */
   public boolean tableIsExist(Class
entityType) throws DbException {
       Table table = Table.get(this, entityType);//根据类对象获取表
       if (table.isCheckedDatabase()) {
           return true;
       }
       Cursor cursor = execQuery("SELECT COUNT(*) AS c FROM sqlite_master WHERE type='table' AND name='" + table.tableName + "'");//查找制定表
       if (cursor != null) {
           try {
               if (cursor.moveToNext()) {
                   int count = cursor.getInt(0);
                   if (count > 0) {//存在指定的表
                       table.setCheckedDatabase(true);
                       return true;
                   }
               }
           } catch (Throwable e) {
               throw new DbException(e);
           } finally {
               IOUtils.closeQuietly(cursor);
           }
       }
       return false;
   }

4.1.2.1.1 获取表对象Table.get(this, entityType);缓存中去找没有去新建

/** 
    * 获取表
    */
   public static synchronized Table get(DbUtils db, Class
entityType) {
       String tableKey = db.getDaoConfig().getDbName() + "#" + entityType.getName();
               Table table = tableMap.get(tableKey);
       if (table == null) {
//没有缓存
           table = new Table(db, entityType);
           tableMap.put(tableKey, table);
       }
       return table;
   }

4.1.2.1.1.1 Table私有构造方法:

private Table(DbUtils db, Class
entityType) {
       this.db = db;
       this.tableName = TableUtils.getTableName(entityType);//获取表名
       this.id = TableUtils.getId(entityType);
       this.columnMap = TableUtils.getColumnMap(entityType);//获取列MAP
       finderMap = new HashMap
();
       for (Column column : columnMap.values()) {
//得到主表列对象
           column.setTable(this);
           if (column instanceof Finder) {
               finderMap.put(column.getColumnName(), (Finder) column);
           }
       }
   }

4.1.2.1.1.1.1 获取表名 TableUtils.getTableName(entityType);

public static String getTableName(Class
entityType) {
       Table table = entityType.getAnnotation(Table.class);
       if (table == null || TextUtils.isEmpty(table.name())) {
//没有注解字段Table
           return entityType.getName().replace('.', '_');
       }
       return table.name();
   }

4.1.2.1.1.1.2 获取表的列对象 TableUtils.getColumnMap(entityType);

/** 
    * 根据类对象获取列对象的MAP
    */
   static synchronized HashMap
getColumnMap(Class
entityType) {
       if (entityColumnsMap.containsKey(entityType.getName())) {
//这个类已经存储过了数据库列对象
           return entityColumnsMap.get(entityType.getName());
       }
       HashMap
columnMap = new HashMap
();
       String primaryKeyFieldName = getPrimaryKeyFieldName(entityType);
       addColumns2Map(entityType, primaryKeyFieldName, columnMap);//缓存类对象的属性指为Columns对象
       entityColumnsMap.put(entityType.getName(), columnMap);//缓存这个数据表的Columns对象MAP集
       return columnMap;
   }

4.1.2.1.1.1.2.1 缓存列对象addColumns2Map(entityType, primaryKeyFieldName, columnMap);

/** 
    * 缓存类对象的属性指为Columns对象
    */
   private static void addColumns2Map(Class
entityType, String primaryKeyFieldName, HashMap
columnMap) {
       if (Object.class.equals(entityType)) return;
       try {
           Field[] fields = entityType.getDeclaredFields();
           for (Field field : fields) {
               if (ColumnUtils.isTransient(field) || Modifier.isStatic(field.getModifiers())) {
//忽略static及注解Transient的属性
                   continue;
               }
               if (ColumnConverterFactory.isSupportColumnConverter(field.getType())) {
//属性字段支持列对象转换
                   if (!field.getName().equals(primaryKeyFieldName)) {
//不是ID字段
                       Column column = new Column(entityType, field);
                       if (!columnMap.containsKey(column.getColumnName())) {
//缓存列对象
                           columnMap.put(column.getColumnName(), column);
                       }
                   }
               } else if (ColumnUtils.isForeign(field)) {
// 属性字段是Foreign注解,从表注解
                   Foreign column = new Foreign(entityType, field);
                   if (!columnMap.containsKey(column.getColumnName())) {
                       columnMap.put(column.getColumnName(), column);
                   }
               } else if (ColumnUtils.isFinder(field)) {
//属性字段是Finder,主表注解
                   Finder column = new Finder(entityType, field);
                   if (!columnMap.containsKey(column.getColumnName())) {
                       columnMap.put(column.getColumnName(), column);
                   }
               }
           }
           if (!Object.class.equals(entityType.getSuperclass())) {
//继续将父类属性字段缓存
               addColumns2Map(entityType.getSuperclass(), primaryKeyFieldName, columnMap);
           }
       } catch (Throwable e) {
           LogUtils.e(e.getMessage(), e);
       }
   }

4.1.2.1.1.1.2.1.1 判断属性字段时候支持列对象转换

   /** 
    * 检查是否支持Column对象转换
    */
   public static boolean isSupportColumnConverter(Class columnType) {
       if (columnType_columnConverter_map.containsKey(columnType.getName())) {
           return true;
       } else if (ColumnConverter.class.isAssignableFrom(columnType)) {
//isAssignableFrom如果调用这个方法的class或接口 与 参数cls表示的类或接口相同,或者是参数cls表示的类或接口的父类,则返回true。
           try {
               ColumnConverter columnConverter = (ColumnConverter) columnType.newInstance();
               if (columnConverter != null) {
                   columnType_columnConverter_map.put(columnType.getName(), columnConverter);
               }
               return columnConverter == null;
           } catch (Throwable e) {
           }
       }
       return false;
   }

4.1.2.1.1.1.2.1.1.1 标准列对象columnType_columnConverter_map内容,上述判断的依据:

  private static final ConcurrentHashMap
columnType_columnConverter_map;
   static {
       columnType_columnConverter_map = new ConcurrentHashMap
();
       BooleanColumnConverter booleanColumnConverter = new BooleanColumnConverter();
       columnType_columnConverter_map.put(boolean.class.getName(), booleanColumnConverter);
       columnType_columnConverter_map.put(Boolean.class.getName(), booleanColumnConverter);
       ByteArrayColumnConverter byteArrayColumnConverter = new ByteArrayColumnConverter();
       columnType_columnConverter_map.put(byte[].class.getName(), byteArrayColumnConverter);
       ByteColumnConverter byteColumnConverter = new ByteColumnConverter();
       columnType_columnConverter_map.put(byte.class.getName(), byteColumnConverter);
       columnType_columnConverter_map.put(Byte.class.getName(), byteColumnConverter);
       CharColumnConverter charColumnConverter = new CharColumnConverter();
       columnType_columnConverter_map.put(char.class.getName(), charColumnConverter);
       columnType_columnConverter_map.put(Character.class.getName(), charColumnConverter);
       DateColumnConverter dateColumnConverter = new DateColumnConverter();
       columnType_columnConverter_map.put(Date.class.getName(), dateColumnConverter);
       DoubleColumnConverter doubleColumnConverter = new DoubleColumnConverter();
       columnType_columnConverter_map.put(double.class.getName(), doubleColumnConverter);
       columnType_columnConverter_map.put(Double.class.getName(), doubleColumnConverter);
       FloatColumnConverter floatColumnConverter = new FloatColumnConverter();
       columnType_columnConverter_map.put(float.class.getName(), floatColumnConverter);
       columnType_columnConverter_map.put(Float.class.getName(), floatColumnConverter);
       IntegerColumnConverter integerColumnConverter = new IntegerColumnConverter();
       columnType_columnConverter_map.put(int.class.getName(), integerColumnConverter);
       columnType_columnConverter_map.put(Integer.class.getName(), integerColumnConverter);
       LongColumnConverter longColumnConverter = new LongColumnConverter();
       columnType_columnConverter_map.put(long.class.getName(), longColumnConverter);
       columnType_columnConverter_map.put(Long.class.getName(), longColumnConverter);
       ShortColumnConverter shortColumnConverter = new ShortColumnConverter();
       columnType_columnConverter_map.put(short.class.getName(), shortColumnConverter);
       columnType_columnConverter_map.put(Short.class.getName(), shortColumnConverter);
       SqlDateColumnConverter sqlDateColumnConverter = new SqlDateColumnConverter();
       columnType_columnConverter_map.put(java.sql.Date.class.getName(), sqlDateColumnConverter);
       StringColumnConverter stringColumnConverter = new StringColumnConverter();
       columnType_columnConverter_map.put(String.class.getName(), stringColumnConverter);
   }

4.1.2.1.1.1.3 获取表的ID属性TableUtils.getId(entityType);

   /** 
    * 获得对象的ID属性
    */
   static synchronized com.lidroid.xutils.db.table.Id getId(Class
entityType) {
       if (Object.class.equals(entityType)) {
           throw new RuntimeException("field 'id' not found");
       }
       if (entityIdMap.containsKey(entityType.getName())) {
           return entityIdMap.get(entityType.getName());
       }
       Field primaryKeyField = null;
       Field[] fields = entityType.getDeclaredFields();//获取声明字段
       if (fields != null) {
           for (Field field : fields) {
               if (field.getAnnotation(Id.class) != null) {
//获取注解ID属性
                   primaryKeyField = field;
                   break;
               }
           }
           if (primaryKeyField == null) {
//没有发现注解ID,根据字段生成ID
               for (Field field : fields) {
                   if ("id".equals(field.getName()) || "_id".equals(field.getName())) {
                       primaryKeyField = field;
                       break;
                   }
               }
           }
       }
       if (primaryKeyField == null) {
           return getId(entityType.getSuperclass());//没有iD属性再去他的父类去找
       }
       com.lidroid.xutils.db.table.Id id = new com.lidroid.xutils.db.table.Id(entityType, primaryKeyField);//生成数据ID对象
       entityIdMap.put(entityType.getName(), id);//存储这个ID对象
       return id;
   }

4.1.2.1.1.1.3.1 ID构造函数:com.lidroid.xutils.db.table.Id id = new com.lidroid.xutils.db.table.Id(entityType, primaryKeyField);

  Id(Class
entityType, Field field) {
       super(entityType, field);
       columnFieldClassName = columnField.getType().getName();//id属性类型名
   }

4.1.2.1.1.1.3.1.1 父类构造函数super(entityType, field);

Column(Class
entityType, Field field) {
       this.columnField = field;
       this.columnConverter = ColumnConverterFactory.getColumnConverter(field.getType());//获取ID属性的ColumnConverter对象
       this.columnName = ColumnUtils.getColumnNameByField(field);
       if (this.columnConverter != null) {
           this.defaultValue = this.columnConverter.getFieldValue(ColumnUtils.getColumnDefaultValue(field));
       } else {
           this.defaultValue = null;
       }
       this.getMethod = ColumnUtils.getColumnGetMethod(entityType, field);
       this.setMethod = ColumnUtils.getColumnSetMethod(entityType, field);
   }

至此Table对象构造完成。接下来如果数据库中的表不存在就去创建。

4.1.2.2 去构建创建表的SQL语句 SqlInfoBuilder.buildCreateTableSqlInfo(this, entityType);

public static SqlInfo buildCreateTableSqlInfo(DbUtils db, Class
entityType) throws DbException {
       Table table = Table.get(db, entityType);
       Id id = table.id;
       StringBuffer sqlBuffer = new StringBuffer();//构造新建数据库SQL语句
       sqlBuffer.append("CREATE TABLE IF NOT EXISTS ");
       sqlBuffer.append(table.tableName);
       sqlBuffer.append(" ( ");
       if (id.isAutoIncrement()) {
//id自增
           sqlBuffer.append(""").append(id.getColumnName()).append(""  ").append("INTEGER PRIMARY KEY AUTOINCREMENT,");
       } else {
           sqlBuffer.append(""").append(id.getColumnName()).append(""  ").append(id.getColumnDbType()).append(" PRIMARY KEY,");
       }
       Collection
columns = table.columnMap.values();//获取表的列对象集合
       for (Column column : columns) {
//组合列名
           if (column instanceof Finder) {
//主表
               continue;
           }
           sqlBuffer.append(""").append(column.getColumnName()).append(""  ");//列名
           sqlBuffer.append(column.getColumnDbType());//类型
           if (ColumnUtils.isUnique(column.getColumnField())) {
//属性
               sqlBuffer.append(" UNIQUE");
           }
           if (ColumnUtils.isNotNull(column.getColumnField())) {
               sqlBuffer.append(" NOT NULL");
           }
           String check = ColumnUtils.getCheck(column.getColumnField());
           if (check != null) {
               sqlBuffer.append(" CHECK(").append(check).append(")");
           }
           sqlBuffer.append(",");
       }
       sqlBuffer.deleteCharAt(sqlBuffer.length() - 1);//删除
       sqlBuffer.append(" )");
       return new SqlInfo(sqlBuffer.toString());
   }

4.1.2.3执行构建数据表的语句 execNonQuery(sqlInfo);

 public void execNonQuery(SqlInfo sqlInfo) throws DbException {
       debugSql(sqlInfo.getSql());
       try {
           if (sqlInfo.getBindArgs() != null) {
               database.execSQL(sqlInfo.getSql(), sqlInfo.getBindArgsAsArray());//有占位符的执行
           } else {
               database.execSQL(sqlInfo.getSql());
           }
       } catch (Throwable e) {
           throw new DbException(e);
       }
   }
4.1.2.4 表构建完成时如果有注解去设置表的默认值String execAfterTableCreated = TableUtils.getExecAfterTableCreated(entityType);
/** 
    * 获取表注解默认值
    */
   public static String getExecAfterTableCreated(Class
entityType) {
       Table table = entityType.getAnnotation(Table.class);
       if (table != null) {
           return table.execAfterTableCreated();
       }
       return null;
   }

4.1.2.5 如果这个默认值语句不为空去执行,设置默认值execNonQuery(execAfterTableCreated);即调用4.1.2.3函数。

至此,对于数据表如果不存在就去创建操作完成。

4.1.3 去构造插入的SQL语句SqlInfoBuilder.buildInsertSqlInfo(this, entity);

   public static SqlInfo buildInsertSqlInfo(DbUtils db, Object entity) throws DbException {
       List
keyValueList = entity2KeyValueList(db, entity);
       if (keyValueList.size() == 0) return null;
       SqlInfo result = new SqlInfo();
       StringBuffer sqlBuffer = new StringBuffer();
       sqlBuffer.append("INSERT INTO ");
       sqlBuffer.append(TableUtils.getTableName(entity.getClass()));//表名
       sqlBuffer.append(" (");
       for (KeyValue kv : keyValueList) {
//封装插入的实体键值对
           sqlBuffer.append(kv.key).append(",");
           result.addBindArgWithoutConverter(kv.value);//添加到属性链表中
       }
       sqlBuffer.deleteCharAt(sqlBuffer.length() - 1);
       sqlBuffer.append(") VALUES (");
       int length = keyValueList.size();
       for (int i = 0; i < length; i++) {
           sqlBuffer.append("?,");
       }
       sqlBuffer.deleteCharAt(sqlBuffer.length() - 1);
       sqlBuffer.append(")");
       result.setSql(sqlBuffer.toString());
       return result;
   }

4.1.4 执行SQL语句执行插入数据操作 execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(this, entity));即调用4.1.2.3函数。

4.1.5 设置数据库事务提交成功setTransactionSuccessful();

private void setTransactionSuccessful() {
       if (allowTransaction) {
           database.setTransactionSuccessful();
       }
   }

至此,数据库插入一条记录完成。

  

5.客户端存储List数据

try {
           mUserFriendDbUtils.saveAll(friends);
       } catch (DbException e) {
           e.printStackTrace();
       }

5.1 存储List数据saveAll

public void saveAll(List
entities) throws DbException {
       if (entities == null || entities.size() == 0) return;
       try {
           beginTransaction();//开启事务
           createTableIfNotExist(entities.get(0).getClass());
           for (Object entity : entities) {
               execNonQuery(SqlInfoBuilder.buildInsertSqlInfo(this, entity));
           }
           setTransactionSuccessful();
       } finally {
           endTransaction();
       }
   }
5.1.1 构造插入语句调用4.1.2.3函数SqlInfoBuilder.buildInsertSqlInfo(this, entity)

后续与上述单项插入相同。

删除数据操作。deleteAll;

6 客户端删除操作

try {
           mUserCircleDbUtils.deleteAll(Circle.class);
       } catch (DbException e) {
           e.printStackTrace();
       }

6.1 执行删除mUserCircleDbUtils.deleteAll(Circle.class);

public void deleteAll(Class
entityType) throws DbException {
       delete(entityType, null);
   }

6.1.1 调用delete(entityType, null);先判断表是否存在,在开启事务管理,执行SQL语句,提交事务成功,关闭事务。

 public void delete(Class
entityType, WhereBuilder whereBuilder) throws DbException {
       if (!tableIsExist(entityType)) return;
       try {
           beginTransaction();
           execNonQuery(SqlInfoBuilder.buildDeleteSqlInfo(this, entityType, whereBuilder));
           setTransactionSuccessful();
       } finally {
           endTransaction();
       }
   }

6.1.1.1 构造删除的SQL语句SqlInfoBuilder.buildDeleteSqlInfo(this, entityType, whereBuilder);

public static SqlInfo buildDeleteSqlInfo(DbUtils db, Class
entityType, WhereBuilder whereBuilder) throws DbException {
       Table table = Table.get(db, entityType);//获取表对象
       StringBuilder sb = new StringBuilder(buildDeleteSqlByTableName(table.tableName));
       if (whereBuilder != null && whereBuilder.getWhereItemSize() > 0) {
           sb.append(" WHERE ").append(whereBuilder.toString());
       }
       return new SqlInfo(sb.toString());
   }

6.1.1.1.1根据表名构造删除SQL语句buildDeleteSqlByTableName(table.tableName)

  private static String buildDeleteSqlByTableName(String tableName) {
       return "DELETE FROM " + tableName;
   }

接下来执行与前面相同。

至此deleteAll操作完成。

查找findAll操作:

7 客户端findAll操作:

  try {
           userList = mUserInforDbUtils.findAll(User.class);
       } catch (DbException e) {
           e.printStackTrace();
       }

7.1查找操作;

public 
List
findAll(Class
entityType) throws DbException {
       return findAll(Selector.from(entityType));
   }
7.1.1 调用findAll操作;
public 
List
findAll(Selector selector) throws DbException {
       if (!tableIsExist(selector.getEntityType())) return null;
       String sql = selector.toString();//构造选择语句
       long seq = CursorUtils.FindCacheSequence.getSeq();
       findTempCache.setSeq(seq);//
       Object obj = findTempCache.get(sql);
       if (obj != null) {
//存在缓存
           return (List
) obj;
       }
       List
result = new ArrayList
();
       Cursor cursor = execQuery(sql);//不存在缓存去执行查询吧
       if (cursor != null) {
           try {
               while (cursor.moveToNext()) {
//存储
                   T entity = (T) CursorUtils.getEntity(this, cursor, selector.getEntityType(), seq);//
                   result.add(entity);
               }
               findTempCache.put(sql, result);
           } catch (Throwable e) {
               throw new DbException(e);
           } finally {
               IOUtils.closeQuietly(cursor);
           }
       }
       return result;
   }
7.1.1.1生产Selector语句selector.toString();
@Override 
   public String toString() {
       StringBuilder result = new StringBuilder();
       result.append("SELECT ");
       result.append("*");
       result.append(" FROM ").append(tableName);
       if (whereBuilder != null && whereBuilder.getWhereItemSize() > 0) {
           result.append(" WHERE ").append(whereBuilder.toString());
       }
       if (orderByList != null) {
           for (int i = 0; i < orderByList.size(); i++) {
               result.append(" ORDER BY ").append(orderByList.get(i).toString());
           }
       }
       if (limit > 0) {
           result.append(" LIMIT ").append(limit);
           result.append(" OFFSET ").append(offset);
       }
       return result.toString();
   }

7.1.1.1.1执行查找语句获得查找的数据CursorUtils.getEntity(this, cursor, selector.getEntityType(), seq);

 public static 
T getEntity(final DbUtils db, final Cursor cursor, Class
entityType, long findCacheSequence) {
       if (db == null || cursor == null) return null;
       EntityTempCache.setSeq(findCacheSequence);
       try {
           Table table = Table.get(db, entityType);
           Id id = table.id;
           String idColumnName = id.getColumnName();
           int idIndex = id.getIndex();
           if (idIndex < 0) {
               idIndex = cursor.getColumnIndex(idColumnName);
           }
           Object idValue = id.getColumnConverter().getFieldValue(cursor, idIndex);
           T entity = EntityTempCache.get(entityType, idValue);
           if (entity == null) {
               entity = entityType.newInstance();
               id.setValue2Entity(entity, cursor, idIndex);
               EntityTempCache.put(entityType, idValue, entity);
           } else {
               return entity;
           }
           int columnCount = cursor.getColumnCount();
           for (int i = 0; i < columnCount; i++) {
               String columnName = cursor.getColumnName(i);
               Column column = table.columnMap.get(columnName);
               if (column != null) {
                   column.setValue2Entity(entity, cursor, i);
               }
           }
           // init finder
           for (Finder finder : table.finderMap.values()) {
               finder.setValue2Entity(entity, null, 0);
           }
           return entity;
       } catch (Throwable e) {
           LogUtils.e(e.getMessage(), e);
       }
       return null;
   }

执行完查询之后缓存并返回结果。

更新操作

8 客户端调用更新

try {
           mArticleDbUtils.update(acceptArticle, "zanCount");
       } catch (DbException e) {
           e.printStackTrace();
       }

8.1 函数update

public void update(Object entity, String... updateColumnNames) throws DbException {
       if (!tableIsExist(entity.getClass())) return;
       try {
           beginTransaction();
           execNonQuery(SqlInfoBuilder.buildUpdateSqlInfo(this, entity, updateColumnNames));
           setTransactionSuccessful();
       } finally {
           endTransaction();
       }
   }

8.1.1构造更新SQL语句SqlInfoBuilder.buildUpdateSqlInfo(this, entity, updateColumnNames)

public static SqlInfo buildUpdateSqlInfo(DbUtils db, Object entity, String... updateColumnNames) throws DbException {
       List
keyValueList = entity2KeyValueList(db, entity);
       if (keyValueList.size() == 0) return null;
       HashSet
updateColumnNameSet = null;
       if (updateColumnNames != null && updateColumnNames.length > 0) {
           updateColumnNameSet = new HashSet
(updateColumnNames.length);
           Collections.addAll(updateColumnNameSet, updateColumnNames);
       }
       Class
entityType = entity.getClass();
       Table table = Table.get(db, entityType);
       Id id = table.id;
       Object idValue = id.getColumnValue(entity);
       if (null == idValue) {
           throw new DbException("this entity[" + entity.getClass() + "]'s id value is null");
       }
       SqlInfo result = new SqlInfo();
       StringBuffer sqlBuffer = new StringBuffer("UPDATE ");
       sqlBuffer.append(table.tableName);
       sqlBuffer.append(" SET ");
       for (KeyValue kv : keyValueList) {
           if (updateColumnNameSet == null || updateColumnNameSet.contains(kv.key)) {
               sqlBuffer.append(kv.key).append("=?,");
               result.addBindArgWithoutConverter(kv.value);
           }
       }
       sqlBuffer.deleteCharAt(sqlBuffer.length() - 1);
       sqlBuffer.append(" WHERE ").append(WhereBuilder.b(id.getColumnName(), "=", idValue));
       result.setSql(sqlBuffer.toString());
       return result;
   }

后续操作与前面相同,支持更新操作完成。

二 致敬原作者,谢谢作者辛苦付出,代码受益匪浅。

三 其他讲解:

架构讲解:

四 源码注释

源码详细注释:

转载地址:https://blog.csdn.net/leif_/article/details/50385084 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Android系统zygote进程初始化及进程孵化
下一篇:XUtils 源码分析(二)--图片缓存模块

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2024年04月08日 13时06分22秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章