createTableIfNotExist

1. createTableIfNotExit


public class DbUtils

 

public void createTableIfNotExist(Class<?> entityType) throws DbException {
    if (!tableIsExist(entityType)) {
        SqlInfo sqlInfo = SqlInfoBuilder.buildCreateTableSqlInfo(this, entityType);
        execNonQuery(sqlInfo);
        String execAfterTableCreated = TableUtils.getExecAfterTableCreated(entityType);
        if (!TextUtils.isEmpty(execAfterTableCreated)) {
            execNonQuery(execAfterTableCreated);
        }
    }
}

 

① 先判斷表是否存在

② 獲取創建表的sql語句,執行語句

③ 類似鉤子的操作,解析@Table註釋中execAfterTableCreated內容,成爲sql

並在表創建成功後執行,如果,sql爲空,則跳過此步驟

 

2. 獲取創建表的sql語句

public class SqlInfoBuilder

 

public static SqlInfo buildCreateTableSqlInfo(DbUtils db, Class<?> entityType) throws DbException {
    Table table = Table.get(db, entityType);
    Id id = table.id;

    StringBuffer sqlBuffer = new StringBuffer();
    sqlBuffer.append("CREATE TABLE IF NOT EXISTS ");
    sqlBuffer.append(table.tableName);
    sqlBuffer.append(" ( ");

    if (id.isAutoIncrement()) {
        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<Column> 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());
}

 

① table對象的獲取,tableIsExist()函數中有提及過程,大體就是獲取主鍵@id以及@column數組信息,放入table對象

② 下面就是一個字符串拼接的活動了(\”java轉義字符==雙引號字符)

+ "CREATE TABLE IF NOT EXISTS "

 

+ entityclassName

 

+ " ( "

 

+ "\”" + @id(主鍵名稱)  + "\”"  + "INTEGER PRIMARY KEY AUTOINCREMENT,"(默認自增)

 

For。。。循環

+ @clumn(列名稱)+(列類型)+" UNIQUE" + " NOT NULL" + " CHECK(" + ")" + ","

結束循環

 

+ 刪掉最後一個","

 

+ " )"

③ 打包成SqlInfo對象,其實就是把生成的sqlBuffer存入SqlInfo對象的sql變量中

 

1) 默認自增(isAutoIncrement

public class Id extends Column

 

public boolean isAutoIncrement() {
    if (!isAutoIncrementChecked) {
        isAutoIncrementChecked = true;
        isAutoIncrement = columnField.getAnnotation(NoAutoIncrement.class) == null
                && AUTO_INCREMENT_TYPES.contains(columnFieldClassName);
    }
    return isAutoIncrement;
}

 

private static final HashSet<String> INTEGER_TYPES = new HashSet<String>(2);
private static final HashSet<String> AUTO_INCREMENT_TYPES = new HashSet<String>(4);

static {
    INTEGER_TYPES.add(int.class.getName());
    INTEGER_TYPES.add(Integer.class.getName());

    AUTO_INCREMENT_TYPES.addAll(INTEGER_TYPES);
    AUTO_INCREMENT_TYPES.add(long.class.getName());
    AUTO_INCREMENT_TYPES.add(Long.class.getName());
}

① isAutoIncrementChecked默認false,所以進入if語句

② 可以看見isAutoIncrementChecked = true

③ 接下來就是真正的判斷條件:

True = 沒有加入註釋NoAutoIncrement 並且 是int或者long類型 會自增

False = 除此之外

 

1) 列類型

回到初始化Column哪裏

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

 

public static ColumnConverter getColumnConverter(Class columnType) {
    if (columnType_columnConverter_map.containsKey(columnType.getName())) {
        return columnType_columnConverter_map.get(columnType.getName());
    } else if (ColumnConverter.class.isAssignableFrom(columnType)) {
        try {
            ColumnConverter columnConverter = (ColumnConverter) columnType.newInstance();
            if (columnConverter != null) {
                columnType_columnConverter_map.put(columnType.getName(), columnConverter);
            }
            return columnConverter;
        } catch (Throwable e) {
        }
    }
    return null;
}

 

private static final ConcurrentHashMap<String, ColumnConverter> columnType_columnConverter_map;

static {
    columnType_columnConverter_map = new ConcurrentHashMap<String, ColumnConverter>();

    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);
}

 

 

① 可以看到最終是從columnType_columnConverter_map緩存中,獲取一個IntegerColumnConverter對象(這裏以int類型舉例)

 

sqlBuffer.append(column.getColumnDbType());

 

public ColumnDbType getColumnDbType() {
    return columnConverter.getColumnDbType();
}

 

public ColumnDbType getColumnDbType() {
    return ColumnDbType.INTEGER;
}

 

public enum ColumnDbType {

    INTEGER("INTEGER"), REAL("REAL"), TEXT("TEXT"), BLOB("BLOB");

    private String value;

    ColumnDbType(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return value;
    }
}

② 看到最終拿到的是一個枚舉,值爲"INTEGER"

 

3. Database執行sql語句創建表

public void createTableIfNotExist(Class<?> entityType) throws DbException {
    if (!tableIsExist(entityType)) {
        SqlInfo sqlInfo = SqlInfoBuilder.buildCreateTableSqlInfo(this, entityType);
        execNonQuery(sqlInfo);
        String execAfterTableCreated = TableUtils.getExecAfterTableCreated(entityType);
        if (!TextUtils.isEmpty(execAfterTableCreated)) {
            execNonQuery(execAfterTableCreated);
        }
    }
}

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);
    }
}

 

Ok,一個簡單的語句執行,創建完畢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章