<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对象(初始化时的对象),tableName(entity类名),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键
② 查看entityIdMap(key=entity类名,vlaue =id对象)缓存中是否有Id缓存,若有,直接返回
③ 没有缓存,从entity类中解析出fields(代表类中字段的数组),开始遍历数组,找出primaryKeyField(@Id主键)
④ 优先查找是否有Annotation(注释)为@id的Field(字段),若无,则选取以“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);
}
① 存储Field到columnField变量
② 存储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,
⑤ 把4的map加入entityColumnsMap缓存中
⑥ 对父类数据迭代,形成map加入entityColumnsMap缓存中
⑦ 这里暂且忽略Foreign和Finder类型,只对Column类型处理
² 获取Table完成,小结:
① Table类中 tableMap缓存中有entity对应的table对象
② TableUtils类中entityColumnsMap缓存中有对应entity的Columns信息
③ TableUtils类中entityIdMap缓存中有对应entity的Id信息
④ 获得entity对应的table对象
2. 回到文章开头的 tableIsExist方法中
if (table.isCheckedDatabase()) {
return true;
}
检查生成的table对象的checkDatabase(boolean变量),查看是否创建,否则继续往下
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
- <2>tableIsExist
- 2
- 2
- 2
- 2
- 2
- 2
- 2
- 2
- 2
- 2
- 2
- 2
- 2
- 2
- >2
- 2
- 2
- CABasicAnimation精讲
- 【腾讯TMQ】糖大夫--测量流程性能监控自动化方案设计
- MySQL 链接eclipse
- 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest
- Ubuntu14.04 下 OpenCV3 安装
- <2>tableIsExist
- 客户端axis调用cxf服务端webservice接口问题
- Android 解决多个Fragment切换时不断实例化
- 输入一个32位的整数a,使用按位异或^运算,生成一个新的32位整数b,使得该整数b的每一位等于原整数a中该位左右两边两个bit位的异或结果
- iOS第三方框架的相关问题
- 功课1-GCD的使用
- Type
- 安卓基础之如何显示网络图片
- <3>createTableIfNotExist