<2>tableIsExist

来源:互联网 发布:中国人民大学网络登录 编辑:程序博客网 时间:2024/06/06 18:51

public classDbUtils

 

public booleantableIsExist(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()) {
                intcount = cursor.getInt(0);
                if (count >0) {
                    table.setCheckedDatabase(true);
                    return true;
                }
            }
        } catch(Throwable e) {
            throw newDbException(e);
        }finally {
            IOUtils.closeQuietly(cursor);
        }
    }

    return false;
}

 

 

1. 获取一个Table对象

public classTable

 

public static synchronizedTable get(DbUtils db,Class<?> entityType) {
    String tableKey = db.getDaoConfig().getDbName() + "#"+ entityType.getName();
    Table table =tableMap.get(tableKey);
    if (table ==null) {
        table = newTable(db,entityType);
        tableMap.put(tableKey,table);
    }

    returntable;
}

 

① Tablekey由数据库名字+#+entity的类名组成,这里的Daoconfig是在DbUtils始化的时候传入了,dbName是用户自己输入的

② Table类中缓存静态tableMap,第一次进来肯定找不到,走table==null

③ 初始化一个Table放入缓存tableMap

 

² 初始化Table

public classTable

 

private Table(DbUtils db,Class<?> entityType) {
    this.db= db;
    this.tableName= TableUtils.getTableName(entityType);
    this.id= TableUtils.getId(entityType);
    this.columnMap= TableUtils.getColumnMap(entityType);

    finderMap= newHashMap<String,Finder>();
    for (Column column :columnMap.values()) {
        column.setTable(this);
        if (columninstanceof Finder) {
            finderMap.put(column.getColumnName(),(Finder) column);
        }
    }
}

① 初始化4个变量,db对象(初始化时的对象),tableNameentity类名),id@Id),数据库组别集合columnMap@column);

② 挑出columnMap中的Finder类型,放入finderMap缓存中

 

 

² tableName的获取

public classTableUtils

 

public staticString getTableName(Class<?> entityType) {
    Tabletable = entityType.getAnnotation(Table.class);
    if (table ==null || TextUtils.isEmpty(table.name())) {
        returnentityType.getName().replace('.','_');
    }
    returntable.name();
}

 

① 获取加了@Table注释的entity

② entity的类名中的“.”更换为“_

③ 返回entity的类名

 

 

² Id的初始化

public classTableUtils

 

static synchronizedcom.lidroid.xutils.db.table.Id getId(Class<?> entityType) {
    if(Object.class.equals(entityType)) {
        throw newRuntimeException("field 'id' not found");
    }

    if(entityIdMap.containsKey(entityType.getName())) {
        returnentityIdMap.get(entityType.getName());
    }

    Field primaryKeyField = null;
    Field[] fields = entityType.getDeclaredFields();
    if (fields !=null) {

        for(Field field : fields) {
            if(field.getAnnotation(Id.class) !=null) {
                primaryKeyField = field;
                break;
            }
        }

        if(primaryKeyField == null) {
            for(Field field : fields) {
                if("id".equals(field.getName()) ||"_id".equals(field.getName())) {
                    primaryKeyField = field;
                    break;
                }
            }
        }
    }

    if(primaryKeyField == null) {
        returngetId(entityType.getSuperclass());
    }

    com.lidroid.xutils.db.table.Id id =new com.lidroid.xutils.db.table.Id(entityType,primaryKeyField);
    entityIdMap.put(entityType.getName(),id);
    return id;
}

 

① 判断entity是否为Object类型,若是,提示找不到Id

② 查看entityIdMapkey=entity类名,vlaue =id对象)缓存中是否有Id缓存,若有,直接返回

③ 没有缓存,从entity类中解析出fields(代表类中字段的数组),开始遍历数组,找出primaryKeyField@Id主键)

④ 优先查找是否有Annotation(注释)为@idField(字段),若无,则选取以“id”和“_id”开始的字段

⑤ 如果还是没有,则是迭代到父类中查找

⑥ 找到primaryKeyField@Id主键),new Id对象,将结果加入entityIdMap缓存,返回结果

 

 

² new Id对象

public classId extendsColumn

Id(Class<?> entityType,Field field) {
    super(entityType,field);
    columnFieldClassName= columnField.getType().getName();
}

 

① Column的构造函数

② columnFieldClassName 存储 @Id字段名

 

                 

² Column的构造函数

public classColumn

 

Column(Class<?> entityType,Field field) {
    this.columnField= field;
    this.columnConverter columnConverter columnConverter columnConverter columnConverter= ColumnConverterFactory.getColumnConverter(field.getType());
    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);
}

 

① 存储FieldcolumnField变量

② 存储Field的类型(类似String.class,Integer.class)到columnConverter

③ 存储Field字段名到columnName

④ 存储Field字段默认值(“” else null)到defaultValue

⑤ 存储Field字段的get/set方法到getMethod/setMethod

 

² 获取get方法

public classColumnUtils

 

public staticMethod getColumnGetMethod(Class<?> entityType,Field field) {
    String fieldName = field.getName();
    Method getMethod =null;
    if (field.getType() ==boolean.class) {
        getMethod = getBooleanColumnGetMethod(entityType,fieldName);
    }
    if(getMethod == null) {
        String methodName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
        try {
            getMethod= entityType.getDeclaredMethod(methodName);
        }catch (NoSuchMethodException e) {
            LogUtils.d(methodName +" not exist");
        }
    }

    if(getMethod == null&& !Object.class.equals(entityType.getSuperclass())) {
        returngetColumnGetMethod(entityType.getSuperclass(),field);
    }
    returngetMethod;
}

 

① If变量类型为boolean,则另行处理

② 其他的,现拼接methodName= “get”+”首字母大写”+”变量剩下的字母”

③ 根据methodName(变量名)获取方法

④ 如果,还是为获取得getMethod则迭代到父类中查找

 

² 回到Table的构造函数,继续columnMap数据库列 信息的获取

public classTable

 

private Table(DbUtils db,Class<?> entityType) {
    this.db= db;
    this.tableName= TableUtils.getTableName(entityType);
    this.id= TableUtils.getId(entityType);
    this.columnMap= TableUtils.getColumnMap(entityType);

    finderMap= newHashMap<String,Finder>();
    for (Column column :columnMap.values()) {
        column.setTable(this);
        if (columninstanceof Finder) {
            finderMap.put(column.getColumnName(),(Finder) column);
        }
    }
}

 

public classTableUtils

 

static synchronizedHashMap<String,Column> getColumnMap(Class<?> entityType) {

    if(entityColumnsMap.containsKey(entityType.getName())) {
        returnentityColumnsMap.get(entityType.getName());
    }

    HashMap<String,Column> columnMap = newHashMap<String,Column>();
    String primaryKeyFieldName =getPrimaryKeyFieldName(entityType);
    addColumns2Map(entityType,primaryKeyFieldName,columnMap);
    entityColumnsMap.put(entityType.getName(),columnMap);

    return columnMap;
}

 

 

private static voidaddColumns2Map(Class<?> entityType,String primaryKeyFieldName,HashMap<String,Column> columnMap) {
    if(Object.class.equals(entityType))return;
    try {
        Field[] fields = entityType.getDeclaredFields();
        for (Field field : fields) {
            if(ColumnUtils.isTransient(field) || Modifier.isStatic(field.getModifiers())) {
                continue;
            }
            if(ColumnConverterFactory.isSupportColumnConverter(field.getType())) {
                if(!field.getName().equals(primaryKeyFieldName)) {
                    Column column = new Column(entityType,field);
                    if (!columnMap.containsKey(column.getColumnName())) {
                        columnMap.put(column.getColumnName(),column);
                    }
                }
            } else if(ColumnUtils.isForeign(field)) {
                Foreign column = new Foreign(entityType,field);
                if (!columnMap.containsKey(column.getColumnName())) {
                    columnMap.put(column.getColumnName(),column);
                }
            } else if(ColumnUtils.isFinder(field)) {
                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);
    }
}

 

 

① 获取的columnns最终存储在entityColumnsMap缓存中

② 通过addColumns2Map函数加入column(数据库列信息)

③ 遍历entity类中的Field字段,剔除@id字段不做处理

④ 用之前介绍的column的构造函数,创建column对象,加入map

⑤ 4map加入entityColumnsMap缓存中

⑥ 对父类数据迭代,形成map加入entityColumnsMap缓存中

⑦ 这里暂且忽略ForeignFinder类型,只对Column类型处理

 

² 获取Table完成,小结:

 

① Table类中 tableMap缓存中有entity对应的table对象

② TableUtils类中entityColumnsMap缓存中有对应entityColumns信息

③ TableUtils类中entityIdMap缓存中有对应entityId信息

④ 获得entity对应的table对象

 

 

2. 回到文章开头的 tableIsExist方法中

if (table.isCheckedDatabase()) {
    return true;
}

 

检查生成的table对象的checkDatabaseboolean变量),查看是否创建,否则继续往下

 

3. 查询此表在数据库中是否存在

Cursor cursor = execQuery("SELECT COUNT(*) AS c FROM sqlite_master WHERE type='table' AND name='"+ table.tableName+ "'");
if (cursor !=null) {
    try{
        if(cursor.moveToNext()) {
            intcount = cursor.getInt(0);
            if (count >0) {
                table.setCheckedDatabase(true);
                return true;
            }
        }
    } catch(Throwable e) {
        throw newDbException(e);
    }finally {
        IOUtils.closeQuietly(cursor);
    }
}

 

① 查询数据库中是否有这个表是否存在

② 小知识:数据库会自行维护一个 sqlite_master 的表,表中记录了数据库中已有表的信息,详细http://blog.sina.com.cn/s/blog_6afeac500100yn9k.html

 

 

 

 

 

 

 

0 0
原创粉丝点击