/** * 检查表是否存在,存在的话检查是否需要改动,添加列字段。 注:sqlite仅仅支持表改名、表添加列两种alter方式。表中修改、刪除列是不被直接支持的。 不能新加主键:The column * may not have a PRIMARY KEY or UNIQUE constraint. * * <p>http://www.sqlite.org/lang_altertable.html */ private boolean checkExistAndColumns(SQLiteDatabase db, EntityTable entityTable) { if (!Checker.isEmpty(mSqlTableList)) { for (SQLiteTable sqlTable : mSqlTableList) { if (entityTable.name.equals(sqlTable.name)) { if (Log.isPrint) Log.d(TAG, "Table [" + entityTable.name + "] Exist"); if (!sqlTable.isTableChecked) { // 表仅进行一次检查,检验是否有新字段加入。 sqlTable.isTableChecked = true; if (Log.isPrint) Log.d(TAG, "Table [" + entityTable.name + "] check column now."); ArrayList<String> newColumns = null; if (entityTable.pmap != null) { for (String col : entityTable.pmap.keySet()) { if (!sqlTable.columns.contains(col)) { if (newColumns == null) newColumns = new ArrayList<String>(); newColumns.add(col); } } } if (!Checker.isEmpty(newColumns)) { sqlTable.columns.addAll(newColumns); int sum = insertNewColunms(db, entityTable.name, newColumns); if (Log.isPrint) Log.i(TAG, "Table [" + entityTable.name + "] add " + sum + " new column"); } } return true; } } } if (Log.isPrint) Log.d(TAG, "Table [" + entityTable.name + "] Not Exist"); return false; }
@Override public <E, T> boolean mapping(Collection<E> col1, Collection<T> col2) { if (Checker.isEmpty(col1) || Checker.isEmpty(col2)) { return false; } acquireReference(); try { return keepMapping(col1, col2) | keepMapping(col2, col1); } catch (Exception e) { e.printStackTrace(); } finally { releaseReference(); } return false; }
public DataBaseConfig( Context context, String dbName, boolean debugged, int dbVersion, OnUpdateListener onUpdateListener) { this.context = context.getApplicationContext(); if (!Checker.isEmpty(dbName)) { this.dbName = dbName; } if (dbVersion > 1) { this.dbVersion = dbVersion; } this.debugged = debugged; this.onUpdateListener = onUpdateListener; }
@Override public int update( Collection<?> collection, ColumnsValue cvs, ConflictAlgorithm conflictAlgorithm) { acquireReference(); try { if (!Checker.isEmpty(collection)) { SQLiteDatabase db = mHelper.getWritableDatabase(); Object entity = collection.iterator().next(); SQLStatement stmt = SQLBuilder.buildUpdateAllSql(entity, cvs, conflictAlgorithm); return stmt.execUpdateCollection(db, collection, cvs, mTableManager); } } catch (Exception e) { e.printStackTrace(); } finally { releaseReference(); } return SQLStatement.NONE; }
@Override public int save(Collection<?> collection) { acquireReference(); try { if (!Checker.isEmpty(collection)) { SQLiteDatabase db = mHelper.getWritableDatabase(); Object entity = collection.iterator().next(); SQLStatement stmt = SQLBuilder.buildReplaceAllSql(entity); mTableManager.checkOrCreateTable(db, entity); return stmt.execInsertCollection(db, collection, mTableManager); } } catch (Exception e) { e.printStackTrace(); } finally { releaseReference(); } return SQLStatement.NONE; }
@Override public <T> T queryById(String id, Class<T> claxx) { acquireReference(); try { SQLiteDatabase db = mHelper.getReadableDatabase(); EntityTable table = TableManager.getTable(claxx); SQLStatement stmt = new QueryBuilder(claxx) .where(table.key.column + "=?", new String[] {id}) .createStatement(); ArrayList<T> list = stmt.query(db, claxx); if (!Checker.isEmpty(list)) { return list.get(0); } } finally { releaseReference(); } return null; }
@Override public int delete(Class<?> claxx, WhereBuilder where) { acquireReference(); try { EntityTable table = TableManager.getTable(claxx); if (table.key != null && !Checker.isEmpty(table.mappingList)) { List<?> list = query(QueryBuilder.create(claxx).columns(new String[] {table.key.column}).where(where)); delete(list); } else { return where.createStatementDelete(claxx).execDelete(mHelper.getWritableDatabase()); } } catch (Exception e) { e.printStackTrace(); } finally { releaseReference(); } return SQLStatement.NONE; }
/** * 插入新列 * * @param tableName * @param columns * @return */ private int insertNewColunms( SQLiteDatabase db, final String tableName, final List<String> columns) { Integer size = null; if (!Checker.isEmpty(columns)) { size = Transaction.execute( db, new Worker<Integer>() { @Override public Integer doTransaction(SQLiteDatabase db) { for (String c : columns) { SQLStatement stmt = SQLBuilder.buildAddColumnSql(tableName, c); stmt.execute(db); } return columns.size(); } }); } return size == null ? 0 : size; }
/** * 初始化全部表及其列名,初始化失败,则无法进行下去。 * * @param db */ private void initAllTablesFromSQLite(SQLiteDatabase db) { synchronized (mSqlTableMap) { if (Checker.isEmpty(mSqlTableMap)) { if (Log.isPrint) { Log.i(TAG, "Initialize SQL table start--------------------->"); } SQLStatement st = SQLBuilder.buildTableObtainAll(); final EntityTable table = getTable(SQLiteTable.class, false); Querier.doQuery( db, st, new Querier.CursorParser() { @Override public void parseEachCursor(SQLiteDatabase db, Cursor c) throws Exception { SQLiteTable sqlTable = new SQLiteTable(); DataUtil.injectDataToObject(c, sqlTable, table); ArrayList<String> colS = getAllColumnsFromSQLite(db, sqlTable.name); if (Checker.isEmpty(colS)) { // 如果读数据库失败了,那么解析建表语句 Log.e(TAG, "读数据库失败了,开始解析建表语句"); colS = transformSqlToColumns(sqlTable.sql); } sqlTable.columns = new HashMap<String, Integer>(); for (String col : colS) { sqlTable.columns.put(col, 1); } if (Log.isPrint) { Log.d(TAG, "Find One SQL Table: " + sqlTable); } mSqlTableMap.put(sqlTable.name, sqlTable); } }); if (Log.isPrint) { Log.i(TAG, "Initialize SQL table end ---------------------> " + mSqlTableMap.size()); } } } }
@Override public int delete(final Collection<?> collection) { acquireReference(); try { if (!Checker.isEmpty(collection)) { EntityTable table = TableManager.getTable(collection.iterator().next()); if (table.key != null) { SQLStatement stmt = SQLBuilder.buildDeleteSql(collection); return stmt.execDeleteCollection( mHelper.getWritableDatabase(), collection, mTableManager); } else { Integer size = Transaction.execute( mHelper.getWritableDatabase(), new Worker<Integer>() { @Override public Integer doTransaction(SQLiteDatabase db) throws Exception { for (Object entity : collection) { SQLBuilder.buildDeleteSql(entity) .execDeleteWithMapping(db, entity, mTableManager); } if (Log.isPrint) { Log.i(TAG, "Exec delete(no primarykey) :" + collection.size()); } return collection.size(); } }); return size == null ? 0 : size; } } } catch (Exception e) { e.printStackTrace(); } finally { releaseReference(); } return SQLStatement.NONE; }
/** * 检查表是否存在,存在的话检查是否需要改动,添加列字段。 注:sqlite仅仅支持表改名、表添加列两种alter方式。表中修改、刪除列是不被直接支持的。 不能新加主键:The column * may not have a PRIMARY KEY or UNIQUE constraint. * * <p>http://www.sqlite.org/lang_altertable.html */ private boolean checkExistAndColumns(SQLiteDatabase db, EntityTable entityTable) { if (!Checker.isEmpty(mSqlTableMap)) { SQLiteTable sqlTable = mSqlTableMap.get(entityTable.name); if (sqlTable != null) { if (Log.isPrint) { Log.d(TAG, "Table [" + entityTable.name + "] Exist"); } if (!sqlTable.isTableChecked) { // 表仅进行一次检查,检验是否有新字段加入。 sqlTable.isTableChecked = true; if (Log.isPrint) { Log.i(TAG, "Table [" + entityTable.name + "] check column now."); } if (entityTable.key != null) { if (sqlTable.columns.get(entityTable.key.column) == null) { SQLStatement stmt = SQLBuilder.buildDropTable(sqlTable.name); stmt.execute(db); if (Log.isPrint) { Log.i( TAG, "Table [" + entityTable.name + "] Primary Key has changed, " + "so drop and recreate it later."); } return false; } } if (entityTable.pmap != null) { ArrayList<String> newColumns = new ArrayList<String>(); for (String col : entityTable.pmap.keySet()) { if (sqlTable.columns.get(col) == null) { newColumns.add(col); } } if (!Checker.isEmpty(newColumns)) { for (String col : newColumns) { sqlTable.columns.put(col, 1); } int sum = insertNewColunms(db, entityTable.name, newColumns); if (Log.isPrint) { if (sum > 0) { Log.i( TAG, "Table [" + entityTable.name + "] add " + sum + " new column : " + newColumns); } else { Log.e( TAG, "Table [" + entityTable.name + "] add " + sum + " new column error : " + newColumns); } } } } } return true; } } if (Log.isPrint) { Log.d(TAG, "Table [" + entityTable.name + "] Not Exist"); } return false; }
/** * 将Cursor的数据注入模型 支持11种基本类型,见{@link ClassUtil#isBaseDataType(Class)} ()} 同时支持序列化对象 * * @param c 数据库Cursor * @param entity 实体对象 */ public static void injectDataToObject(Cursor c, Object entity, EntityTable table) throws Exception { Field f; Property p; for (int i = 0, size = c.getColumnCount(); i < size; i++) { // long start = System.nanoTime(); String col = c.getColumnName(i); p = null; if (!Checker.isEmpty(table.pmap)) { p = table.pmap.get(col); } if (p == null && table.key != null && col.equals(table.key.column)) { p = table.key; } if (p == null) { if (OrmLog.isPrint) { OrmLog.w(TAG, "数据库字段[" + col + "]已在实体中被移除"); } continue; } f = p.field; f.setAccessible(true); // Log.i(TAG, "parse pre after " + ((System.nanoTime() - start) / 1000)); // start = System.nanoTime(); switch (p.classType) { case CLASS_TYPE_STRING: f.set(entity, c.getString(i)); break; case CLASS_TYPE_BOOLEAN: f.set(entity, Boolean.parseBoolean(c.getString(i))); break; case CLASS_TYPE_LONG: f.set(entity, c.getLong(i)); break; case CLASS_TYPE_INT: f.set(entity, c.getInt(i)); break; case CLASS_TYPE_DOUBLE: f.set(entity, c.getDouble(i)); break; case CLASS_TYPE_FLOAT: f.set(entity, c.getFloat(i)); break; case CLASS_TYPE_SHORT: f.set(entity, c.getShort(i)); break; case CLASS_TYPE_BYTE: if (c.getString(i) != null) { f.set(entity, Byte.parseByte(c.getString(i))); } break; case CLASS_TYPE_BYTE_ARRAY: f.set(entity, c.getBlob(i)); break; case CLASS_TYPE_CHAR: String value = c.getString(i); if (!Checker.isEmpty(value)) { f.set(entity, value.charAt(0)); } break; case CLASS_TYPE_DATE: Long time = c.getLong(i); if (time != null) { f.set(entity, new Date(time)); } break; case CLASS_TYPE_SERIALIZABLE: byte[] bytes = c.getBlob(i); if (bytes != null) { // 序列化的对象 f.set(entity, byteToObject(bytes)); } break; default: break; } // Log.i(TAG, "parse set after " + ((System.nanoTime() - start) / 1000)); } }
/** * global lock synchronized * * @param db */ private void initAllTablesFromSQLite(SQLiteDatabase db) { synchronized (instance) { if (Checker.isEmpty(mSqlTableList)) mSqlTableList = TableUtil.getAllTablesFromSQLite(db); } }
private <E, T> boolean keepMapping(Collection<E> col1, Collection<T> col2) throws IllegalAccessException, InstantiationException { Class claxx1 = col1.iterator().next().getClass(); Class claxx2 = col2.iterator().next().getClass(); EntityTable table1 = TableManager.getTable(claxx1); EntityTable table2 = TableManager.getTable(claxx2); if (table1.mappingList != null) { for (MapProperty mp : table1.mappingList) { Class itemClass; Class fieldClass = mp.field.getType(); if (mp.isToMany()) { // N对多关系 if (ClassUtil.isCollection(fieldClass)) { itemClass = FieldUtil.getGenericType(mp.field); } else { throw new RuntimeException( "OneToMany and ManyToMany Relation, You must use collection object"); } } else { itemClass = fieldClass; } if (itemClass == claxx2) { ArrayList<String> key1List = new ArrayList<String>(); HashMap<String, Object> map1 = new HashMap<String, Object>(); // 构建第1个对象的key集合以及value映射 for (Object o1 : col1) { if (o1 != null) { Object key1 = FieldUtil.get(table1.key.field, o1); if (key1 != null) { key1List.add(key1.toString()); map1.put(key1.toString(), o1); } } } ArrayList<Relation> mapList = queryRelation(claxx1, claxx2, key1List, null); if (!Checker.isEmpty(mapList)) { HashMap<String, Object> map2 = new HashMap<String, Object>(); // 构建第2个对象的value映射 for (Object o2 : col2) { if (o2 != null) { Object key2 = FieldUtil.get(table2.key.field, o2); if (key2 != null) { map2.put(key2.toString(), o2); } } } for (Relation m : mapList) { Object obj1 = map1.get(m.key1); Object obj2 = map2.get(m.key2); if (obj1 != null && obj2 != null) { if (mp.isToMany()) { // N对多关系 if (ClassUtil.isCollection(fieldClass)) { Collection col = (Collection) FieldUtil.get(mp.field, obj1); if (col == null) { col = (Collection) fieldClass.newInstance(); FieldUtil.set(mp.field, obj1, col); } col.add(obj2); } else { throw new RuntimeException( "OneToMany and ManyToMany Relation, You must use collection object"); } } else { FieldUtil.set(mp.field, obj1, obj2); } } } return true; } } } } return false; }