package com.litesuits.orm.db.assit; import android.util.SparseArray; import com.litesuits.orm.db.TableManager; import com.litesuits.orm.db.annotation.*; import com.litesuits.orm.db.enums.AssignType; import com.litesuits.orm.db.model.*; import com.litesuits.orm.db.model.MapInfo.MapTable; import com.litesuits.orm.db.utils.ClassUtil; import com.litesuits.orm.db.utils.DataUtil; import com.litesuits.orm.db.utils.FieldUtil; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map.Entry; public class SQLBuilder { public static final int TYPE_INSERT = 1; public static final int TYPE_REPLACE = 2; public static final int TYPE_UPDATE = 3; public static final String DELETE_FROM = "DELETE FROM "; public static final String SELECT_TABLES = "SELECT * FROM sqlite_master WHERE type='table' ORDER BY name"; public static final String PRAGMA_TABLE_INFO = "PRAGMA table_info("; public static final String PARENTHESES_LEFT = "("; public static final String PARENTHESES_RIGHT = ")"; public static final String IN = " IN "; public static final String SELECT_MAX = "SELECT MAX "; public static final String SELECT_ANY_FROM = "SELECT * FROM "; public static final String SELECT = "SELECT "; public static final String FROM = " FROM "; public static final String ORDER_BY = " ORDER BY "; public static final String ASC = " ASC "; public static final String DESC = " DESC "; public static final String LIMIT = " LIMIT "; public static final String DROP_TABLE = "DROP TABLE "; public static final String CREATE = "CREATE "; public static final String TEMP = "TEMP "; public static final String TABLE_IF_NOT_EXISTS = "TABLE IF NOT EXISTS "; public static final String PRIMARY_KEY_AUTOINCREMENT = "PRIMARY KEY AUTOINCREMENT "; public static final String PRIMARY_KEY = "PRIMARY KEY "; public static final String COMMA = ","; public static final String TWO_HOLDER = "(?,?)"; public static final String BLANK = " "; public static final String NOT_NULL = "NOT NULL "; public static final String DEFAULT = "DEFAULT "; public static final String UNIQUE = "UNIQUE "; public static final String ON_CONFLICT = "ON CONFLICT "; public static final String CHECK = "CHECK "; public static final String COLLATE = "COLLATE "; public static final String COMMA_HOLDER = ",?"; public static final String EQUALS_HOLDER = "=?"; public static final String HOLDER = "?"; public static final String INSERT = "INSERT "; public static final String REPLACE = "REPLACE "; public static final String INTO = "INTO "; public static final String VALUES = "VALUES"; public static final String UPDATE = "UPDATE "; public static final String SET = " SET "; public static final String WHERE = " WHERE "; public static final String AND = " AND "; public static final String OR = " OR "; public static final String NOT = " NOT "; public static final String ASTERISK = "*"; /** * 构建【获取SQLite全部表】sql语句 */ public static SQLStatement buildTableObtainAll() { return new SQLStatement(SELECT_TABLES, null); } /** * 构建【获取SQLite全部表】sql语句 */ public static SQLStatement buildColumnsObtainAll(String table) { return new SQLStatement(PRAGMA_TABLE_INFO + table + PARENTHESES_RIGHT, null); } /** * 构建【获取最新插入的数据的主键】sql语句 */ public static SQLStatement buildGetLastRowId(EntityTable table) { return new SQLStatement(SELECT_MAX + PARENTHESES_LEFT + table.key.column + PARENTHESES_RIGHT + FROM + table.name, null); } /** * 构建【表删除】sql语句 */ public static SQLStatement buildDropTable(EntityTable table) { return new SQLStatement(DROP_TABLE + table.name, null); } /** * 构建【表删除】sql语句 */ public static SQLStatement buildDropTable(String tableName) { return new SQLStatement(DROP_TABLE + tableName, null); } /** * 构建【表】sql语句 * * create [temp] table if not exists (table-name) (co1 TEXT, co2 TEXT, UNIQUE (co1, co2)) * * such as : CREATE TABLE IF NOT EXISTS table-name (_id INTEGER PRIMARY KEY AUTOINCREMENT ,xx TEXT) */ public static SQLStatement buildCreateTable(EntityTable table) { StringBuilder sb = new StringBuilder(); sb.append(CREATE); if (table.getAnnotation(Temporary.class) != null) { sb.append(TEMP); } sb.append(TABLE_IF_NOT_EXISTS).append(table.name).append(PARENTHESES_LEFT); boolean hasKey = false; if (table.key != null) { hasKey = true; if (table.key.assign == AssignType.AUTO_INCREMENT) { sb.append(table.key.column).append(DataUtil.INTEGER).append(PRIMARY_KEY_AUTOINCREMENT); } else { sb.append(table.key.column).append(DataUtil.getSQLDataType(table.key.classType)).append(PRIMARY_KEY); } } if (!Checker.isEmpty(table.pmap)) { if (hasKey) { sb.append(COMMA); } boolean needComma = false; SparseArray<ArrayList<String>> combineUniqueMap = null; for (Entry<String, Property> en : table.pmap.entrySet()) { if (needComma) { sb.append(COMMA); } else { needComma = true; } String key = en.getKey(); sb.append(key); if (en.getValue() == null) { sb.append(DataUtil.TEXT); } else { Field f = en.getValue().field; sb.append(DataUtil.getSQLDataType(en.getValue().classType)); if (f.getAnnotation(NotNull.class) != null) { sb.append(NOT_NULL); } if (f.getAnnotation(Default.class) != null) { sb.append(DEFAULT); sb.append(f.getAnnotation(Default.class).value()); sb.append(BLANK); } if (f.getAnnotation(Unique.class) != null) { sb.append(UNIQUE); } if (f.getAnnotation(Conflict.class) != null) { sb.append(ON_CONFLICT); sb.append(f.getAnnotation(Conflict.class).value().getSql()); sb.append(BLANK); } if (f.getAnnotation(Check.class) != null) { sb.append(CHECK + PARENTHESES_LEFT); sb.append(f.getAnnotation(Check.class).value()); sb.append(PARENTHESES_RIGHT); sb.append(BLANK); } if (f.getAnnotation(Collate.class) != null) { sb.append(COLLATE); sb.append(f.getAnnotation(Collate.class).value()); sb.append(BLANK); } UniqueCombine uc = f.getAnnotation(UniqueCombine.class); if (uc != null) { if (combineUniqueMap == null) { combineUniqueMap = new SparseArray<ArrayList<String>>(); } ArrayList<String> list = combineUniqueMap.get(uc.value()); if (list == null) { list = new ArrayList<String>(); combineUniqueMap.put(uc.value(), list); } list.add(key); } } } if (combineUniqueMap != null) { for (int i = 0, nsize = combineUniqueMap.size(); i < nsize; i++) { ArrayList<String> list = combineUniqueMap.valueAt(i); if (list.size() > 1) { sb.append(COMMA).append(UNIQUE).append(PARENTHESES_LEFT); for (int j = 0, size = list.size(); j < size; j++) { if (j != 0) { sb.append(COMMA); } sb.append(list.get(j)); } sb.append(PARENTHESES_RIGHT); } } } } sb.append(PARENTHESES_RIGHT); return new SQLStatement(sb.toString(), null); } /** * 构建 insert 语句 */ public static SQLStatement buildInsertSql(Object entity, ConflictAlgorithm algorithm) { return buildInsertSql(entity, true, TYPE_INSERT, algorithm); } /** * 构建批量 insert all 语句,sql不绑定值,执行时时会遍历绑定值。 */ public static SQLStatement buildInsertAllSql(Object entity, ConflictAlgorithm algorithm) { return buildInsertSql(entity, false, TYPE_INSERT, algorithm); } /** * 构建 replace 语句 */ public static SQLStatement buildReplaceSql(Object entity) { return buildInsertSql(entity, true, TYPE_REPLACE, null); } /** * 构建批量 replace all 语句,sql不绑定值,执行时时会遍历绑定值。 */ public static SQLStatement buildReplaceAllSql(Object entity) { return buildInsertSql(entity, false, TYPE_REPLACE, null); } /** * 构建 insert SQL 语句 * insert(replace) [algorithm] into {table} (key,col...) values (?,?...) * * @param entity 实体 * @param needValue 构建批量sql不需要赋值,执行时临时遍历赋值 * @param type {@link #TYPE_INSERT} or {@link #TYPE_REPLACE} * @param algorithm {@link ConflictAlgorithm} */ private static SQLStatement buildInsertSql(Object entity, boolean needValue, int type, ConflictAlgorithm algorithm) { SQLStatement stmt = new SQLStatement(); try { EntityTable table = TableManager.getTable(entity); StringBuilder sql = new StringBuilder(128); switch (type) { case TYPE_REPLACE: sql.append(REPLACE).append(INTO); break; case TYPE_INSERT: default: sql.append(INSERT); if (algorithm != null) { sql.append(algorithm.getAlgorithm()).append(INTO); } else { sql.append(INTO); } break; } sql.append(table.name); sql.append(PARENTHESES_LEFT); sql.append(table.key.column); // 分两部分构建SQL语句,用一个for循环完成SQL构建和值的反射获取,以提高效率。 StringBuilder value = new StringBuilder(); value.append(PARENTHESES_RIGHT).append(VALUES).append(PARENTHESES_LEFT).append(HOLDER); int size = 1, i = 0; if (!Checker.isEmpty(table.pmap)) { size += table.pmap.size(); } Object[] args = null; if (needValue) { args = new Object[size]; args[i++] = FieldUtil.getAssignedKeyObject(table.key, entity); } if (!Checker.isEmpty(table.pmap)) { for (Entry<String, Property> en : table.pmap.entrySet()) { // 后构造列名和占位符 sql.append(COMMA).append(en.getKey()); value.append(COMMA_HOLDER); // 构造列值 if (needValue) { args[i] = FieldUtil.get(en.getValue().field, entity); } i++; } } sql.append(value).append(PARENTHESES_RIGHT); stmt.bindArgs = args; stmt.sql = sql.toString(); } catch (Exception e) { e.printStackTrace(); } return stmt; } /** * 获取 insert 语句被存储对象的参数 */ public static Object[] buildInsertSqlArgsOnly(Object entity) throws IllegalAccessException { EntityTable table = TableManager.getTable(entity); int size = 1, i = 0; if (!Checker.isEmpty(table.pmap)) { size += table.pmap.size(); } Object[] args = new Object[size]; args[i++] = FieldUtil.getAssignedKeyObject(table.key, entity); if (!Checker.isEmpty(table.pmap)) { for (Property p : table.pmap.values()) { // 后构造列名和占位符 args[i++] = FieldUtil.get(p.field, entity); } } return args; } /** * 构建 update 语句 */ public static SQLStatement buildUpdateSql(Object entity, ColumnsValue cvs, ConflictAlgorithm algorithm) { return buildUpdateSql(entity, cvs, algorithm, true); } /** * 构建批量 update all 语句,sql不绑定值,执行时时会遍历绑定值。 */ public static SQLStatement buildUpdateAllSql(Object entity, ColumnsValue cvs, ConflictAlgorithm algorithm) { return buildUpdateSql(entity, cvs, algorithm, false); } /** * 构建 update SQL语句 * update [algorithm] {table} set col=?,... where key=value * * @param entity 实体 * @param cvs 更新的列,为NULL则更新全部 * @param algorithm {@link ConflictAlgorithm} * @param needValue 构建批量sql不需要赋值,执行时临时遍历赋值(批量更新时,仅构建sql语句,插入操作时循环赋值) */ private static SQLStatement buildUpdateSql(Object entity, ColumnsValue cvs, ConflictAlgorithm algorithm, boolean needValue) { SQLStatement stmt = new SQLStatement(); try { EntityTable table = TableManager.getTable(entity); StringBuilder sql = new StringBuilder(128); sql.append(UPDATE); if (algorithm != null) { sql.append(algorithm.getAlgorithm()); } sql.append(table.name); sql.append(SET); // 分两部分构建SQL语句,用一个for循环完成SQL构建和值的反射获取,以提高效率。 int size = 1, i = 0; Object[] args = null; if (cvs != null && cvs.checkColumns()) { if (needValue) { size += cvs.columns.length; args = new Object[size]; } for (; i < cvs.columns.length; i++) { if (i > 0) { sql.append(COMMA); } sql.append(cvs.columns[i]).append(EQUALS_HOLDER); if (needValue) { args[i] = cvs.getValue(cvs.columns[i]); if (args[i] == null) { args[i] = FieldUtil.get(table.pmap.get(cvs.columns[i]).field, entity); } } } } else if (!Checker.isEmpty(table.pmap)) { if (needValue) { size += table.pmap.size(); args = new Object[size]; } for (Entry<String, Property> en : table.pmap.entrySet()) { if (i > 0) { sql.append(COMMA); } sql.append(en.getKey()).append(EQUALS_HOLDER); if (needValue) { args[i] = FieldUtil.get(en.getValue().field, entity); } i++; } } else if (needValue) { args = new Object[size]; } if (needValue) { args[size - 1] = FieldUtil.getAssignedKeyObject(table.key, entity); } sql.append(WHERE).append(table.key.column).append(EQUALS_HOLDER); stmt.sql = sql.toString(); stmt.bindArgs = args; } catch (Exception e) { e.printStackTrace(); } return stmt; } /** * 获取 insert 语句被存储对象的参数 */ public static Object[] buildUpdateSqlArgsOnly(Object entity, ColumnsValue cvs) throws IllegalAccessException { EntityTable table = TableManager.getTable(entity); // 分两部分构建SQL语句,用一个for循环完成SQL构建和值的反射获取,以提高效率。 int size = 1, i = 0; Object[] args = null; if (cvs != null && cvs.checkColumns()) { size += cvs.columns.length; args = new Object[size]; for (; i < cvs.columns.length; i++) { args[i] = cvs.getValue(cvs.columns[i]); if (args[i] == null) { args[i] = FieldUtil.get(table.pmap.get(cvs.columns[i]).field, entity); } } } else if (!Checker.isEmpty(table.pmap)) { size += table.pmap.size(); args = new Object[size]; for (Entry<String, Property> en : table.pmap.entrySet()) { args[i] = FieldUtil.get(en.getValue().field, entity); i++; } } else { args = new Object[size]; } args[size - 1] = FieldUtil.getAssignedKeyObject(table.key, entity); return args; } /** * 构建 update SQL语句 * update [algorithm] {table} set col1=?, col2=? where ... * * @param where 更新语句 * @param cvs 更新的列,为NULL则更新全部 * @param algorithm {@link ConflictAlgorithm} */ public static SQLStatement buildUpdateSql(WhereBuilder where, ColumnsValue cvs, ConflictAlgorithm algorithm) { SQLStatement stmt = new SQLStatement(); try { EntityTable table = TableManager.getTable(where.getTableClass()); StringBuilder sql = new StringBuilder(128); sql.append(UPDATE); if (algorithm != null) { sql.append(algorithm.getAlgorithm()); } sql.append(table.name); sql.append(SET); // 分两部分构建SQL语句,用一个for循环完成SQL构建和值的反射获取,以提高效率。 Object[] args; if (cvs != null && cvs.checkColumns()) { Object[] wArgs = where.getWhereArgs(); if (wArgs != null) { args = new Object[cvs.columns.length + wArgs.length]; } else { args = new Object[cvs.columns.length]; } int i = 0; for (; i < cvs.columns.length; i++) { if (i > 0) { sql.append(COMMA); } sql.append(cvs.columns[i]).append(EQUALS_HOLDER); args[i] = cvs.getValue(cvs.columns[i]); } if (wArgs != null) { for (Object o : wArgs) { args[i++] = o; } } } else { args = where.getWhereArgs(); } sql.append(where.createWhereString()); stmt.sql = sql.toString(); stmt.bindArgs = args; } catch (Exception e) { e.printStackTrace(); } return stmt; } /** * 构建删除sql语句 * delete from [table] where key=? */ public static SQLStatement buildDeleteSql(Object entity) { SQLStatement stmt = new SQLStatement(); try { EntityTable table = TableManager.getTable(entity); if (table.key != null) { stmt.sql = DELETE_FROM + table.name + WHERE + table.key.column + EQUALS_HOLDER; stmt.bindArgs = new String[]{String.valueOf(FieldUtil.get(table.key.field, entity))}; } else if (!Checker.isEmpty(table.pmap)) { StringBuilder sb = new StringBuilder(); sb.append(DELETE_FROM).append(table.name).append(WHERE); Object[] args = new Object[table.pmap.size()]; int i = 0; for (Entry<String, Property> en : table.pmap.entrySet()) { if (i == 0) { sb.append(en.getKey()).append(EQUALS_HOLDER); } else { sb.append(AND).append(en.getKey()).append(EQUALS_HOLDER); } args[i++] = FieldUtil.get(en.getValue().field, entity); } stmt.sql = sb.toString(); stmt.bindArgs = args; } } catch (Exception e) { e.printStackTrace(); } return stmt; } /** * 构建批量删除sql语句 * delete from [table] where [key] in (?,?) * * 注意:collection 数量不能超过999 */ public static SQLStatement buildDeleteSql(Collection<?> collection) { SQLStatement stmt = new SQLStatement(); try { StringBuilder sb = new StringBuilder(256); EntityTable table = null; Object[] args = new Object[collection.size()]; int i = 0; for (Object entity : collection) { if (i == 0) { table = TableManager.getTable(entity); sb.append(DELETE_FROM).append(table.name).append(WHERE) .append(table.key.column).append(IN).append(PARENTHESES_LEFT).append(HOLDER); } else { sb.append(COMMA_HOLDER); } args[i++] = FieldUtil.get(table.key.field, entity); } sb.append(PARENTHESES_RIGHT); stmt.sql = sb.toString(); stmt.bindArgs = args; } catch (Exception e) { e.printStackTrace(); } return stmt; } /** * 构建全部删除sql语句 * delete from {table} */ public static SQLStatement buildDeleteAllSql(Class<?> claxx) { SQLStatement stmt = new SQLStatement(); EntityTable table = TableManager.getTable(claxx); stmt.sql = DELETE_FROM + table.name; return stmt; } /** * 构建部分删除sql语句 * delete form {table} where {key} in (select {key} from {table} order by {col} ASC limit {start},{end}) ) */ public static SQLStatement buildDeleteSql(Class<?> claxx, long start, long end, String orderAscColumn) { SQLStatement stmt = new SQLStatement(); EntityTable table = TableManager.getTable(claxx); String key = table.key.column; String orderBy = Checker.isEmpty(orderAscColumn) ? key : orderAscColumn; StringBuilder sb = new StringBuilder(); sb.append(DELETE_FROM).append(table.name).append(WHERE).append(key) .append(IN).append(PARENTHESES_LEFT) .append(SELECT).append(key) .append(FROM).append(table.name) .append(ORDER_BY).append(orderBy) .append(ASC).append(LIMIT).append(start).append(COMMA).append(end).append(PARENTHESES_RIGHT); stmt.sql = sb.toString(); return stmt; } /** * 构建添加列语句 * alter {table} add column {col} */ public static SQLStatement buildAddColumnSql(String tableName, String column) { SQLStatement stmt = new SQLStatement(); stmt.sql = "ALTER TABLE " + tableName + " ADD COLUMN " + column; return stmt; } /** * 构建添加主键列语句 * * @param tableName * @param column * @return */ //public static SQLStatement buildAddPrimaryKeySql(String tableName, String column, boolean autoIncrement) { // SQLStatement stmt = new SQLStatement(); // if (autoIncrement) { // stmt.sql = "ALTER TABLE " + tableName + " ADD COLUMN " + column + " INTEGER UNIQUE AUTOINCREMENT"; // } else { // stmt.sql = "ALTER TABLE " + tableName + " ADD COLUMN " + column + " TEXT UNIQUE"; // } // return stmt; //} /** * 构建关系映射语句 */ public static MapInfo buildDelAllMappingSql(Class claxx) { EntityTable table1 = TableManager.getTable(claxx); if (!Checker.isEmpty(table1.mappingList)) { try { MapInfo mapInfo = new MapInfo(); for (MapProperty map : table1.mappingList) { EntityTable table2 = TableManager.getTable(getTypeByRelation(map)); // add map table info String mapTableName = TableManager.getMapTableName(table1, table2); MapTable mi = new MapTable(mapTableName, table1.name, table2.name); mapInfo.addTable(mi); // add delete mapping sql to map info SQLStatement st = buildMappingDeleteAllSql(table1, table2); mapInfo.addDelOldRelationSQL(st); } return mapInfo; } catch (Exception e) { e.printStackTrace(); } } return null; } /** * 构建关系映射语句 * 1. 如果是插入或更新数据,先删除旧映射,再建立新映射。 * 2. 如果是删除,直接删除就映射即可。 */ public static MapInfo buildMappingInfo(Object entity, boolean insertNew, TableManager tableManager) { EntityTable table1 = TableManager.getTable(entity); if (!Checker.isEmpty(table1.mappingList)) { try { Object key1 = FieldUtil.get(table1.key.field, entity); if (key1 == null) { return null; } MapInfo mapInfo = new MapInfo(); for (MapProperty map : table1.mappingList) { EntityTable table2 = TableManager.getTable(getTypeByRelation(map)); // add map table info String mapTableName = TableManager.getMapTableName(table1, table2); MapTable mi = new MapTable(mapTableName, table1.name, table2.name); mapInfo.addTable(mi); if (tableManager.isSQLMapTableCreated(table1.name, table2.name)) { // add delete mapping sql to map info SQLStatement st = buildMappingDeleteSql(key1, table1, table2); mapInfo.addDelOldRelationSQL(st); } if (insertNew) { // also insert new mapping relation Object mapObject = FieldUtil.get(map.field, entity); if (mapObject != null) { if (map.isToMany()) { ArrayList<SQLStatement> sqlList; SQLStatement addSql; if (mapObject instanceof Collection<?>) { sqlList = buildMappingToManySql(key1, table1, table2, (Collection<?>) mapObject); //addSql = buildMappingToManySqlFragment(key1, table1, table2, // (Collection<?>) mapObject); } else if (mapObject instanceof Object[]) { sqlList = buildMappingToManySql(key1, table1, table2, Arrays.asList((Object[]) mapObject)); //addSql = buildMappingToManySqlFragment(key1, table1, table2, // Arrays.asList((Object[]) mapObject)); } else { throw new RuntimeException("OneToMany and ManyToMany Relation," + " You must use array or collection object"); } if (Checker.isEmpty(sqlList)) { mapInfo.addNewRelationSQL(sqlList); } //if (addSql != null) { // mapInfo.addNewRelationSQL(addSql); //} } else { SQLStatement st = buildMappingToOneSql(key1, table1, table2, mapObject); if (st != null) { mapInfo.addNewRelationSQL(st); } } } } } return mapInfo; } catch (Exception e) { e.printStackTrace(); } } return null; } private static Class getTypeByRelation(MapProperty mp) { Class calxx; if (mp.isToMany()) { Class c = mp.field.getType(); if (ClassUtil.isCollection(c)) { calxx = FieldUtil.getGenericType(mp.field); } else if (ClassUtil.isArray(c)) { calxx = FieldUtil.getComponentType(mp.field); } else { throw new RuntimeException( "OneToMany and ManyToMany Relation, you must use collection or array object"); } } else { calxx = mp.field.getType(); } return calxx; } /** * 构建删除全部映射关系数据语句 * delete from {map table} */ private static SQLStatement buildMappingDeleteAllSql(EntityTable table1, EntityTable table2) throws IllegalArgumentException, IllegalAccessException { if (table2 != null) { String mapTableName = TableManager.getMapTableName(table1, table2); SQLStatement stmt = new SQLStatement(); stmt.sql = DELETE_FROM + mapTableName; return stmt; } return null; } /** * 构建SQL语句:删除Key1的全部映射关系数据 * delete from {map table} where {key1=?} */ public static SQLStatement buildMappingDeleteSql(Object key1, EntityTable table1, EntityTable table2) throws IllegalArgumentException, IllegalAccessException { if (table2 != null) { String mapTableName = TableManager.getMapTableName(table1, table2); return buildMappingDeleteSql(mapTableName, key1, table1); } return null; } /** * 构建SQL语句:删除Key1的全部映射关系数据 * delete from {map table} where {key1=?} */ public static SQLStatement buildMappingDeleteSql(String mapTableName, Object key1, EntityTable table1) throws IllegalArgumentException, IllegalAccessException { if (mapTableName != null) { SQLStatement stmt = new SQLStatement(); stmt.sql = DELETE_FROM + mapTableName + WHERE + table1.name + EQUALS_HOLDER; stmt.bindArgs = new Object[]{key1}; return stmt; } return null; } /** * 构建N对多关系SQL * replace into {table} (col1=?,col2=?) values (v1,v2),(va,vb)... */ public static <T> ArrayList<SQLStatement> buildMappingToManySql(final Object key1, final EntityTable table1, final EntityTable table2, Collection<T> coll) throws Exception { final ArrayList<SQLStatement> sqlList = new ArrayList<SQLStatement>(); // this will take 2 "?" holders CollSpliter.split(coll, SQLStatement.IN_TOP_LIMIT / 2, new CollSpliter.Spliter<T>() { @Override public int oneSplit(ArrayList<T> list) throws Exception { SQLStatement sql = buildMappingToManySqlFragment(key1, table1, table2, list); if (sql != null) { sqlList.add(sql); } return 0; } }); return sqlList; } /** * 构建N对多关系SQL * replace into {table} (col1=?,col2=?) values (v1,v2),(va,vb)... * (注意:collection 数量) */ private static SQLStatement buildMappingToManySqlFragment(Object key1, EntityTable table1, EntityTable table2, Collection<?> coll) throws IllegalArgumentException, IllegalAccessException { String mapTableName = TableManager.getMapTableName(table1, table2); if (!Checker.isEmpty(coll)) { boolean isF = true; StringBuilder values = new StringBuilder(128); ArrayList<String> list = new ArrayList<String>(); String key1Str = String.valueOf(key1); for (Object o : coll) { Object key2 = FieldUtil.getAssignedKeyObject(table2.key, o); if (key2 != null) { if (isF) { values.append(TWO_HOLDER); isF = false; } else { values.append(COMMA).append(TWO_HOLDER); } list.add(key1Str); list.add(String.valueOf(key2)); } } Object[] args = list.toArray(new String[list.size()]); if (!Checker.isEmpty(args)) { SQLStatement stmt = new SQLStatement(); stmt.sql = REPLACE + INTO + mapTableName + PARENTHESES_LEFT + table1.name + COMMA + table2.name + PARENTHESES_RIGHT + VALUES + values; stmt.bindArgs = args; return stmt; } } return null; } /** * 构建N对一关系存储语句 * insert into {table} (key1,key2) values (?,?) */ public static SQLStatement buildMappingToOneSql(Object key1, EntityTable table1, EntityTable table2, Object obj) throws IllegalArgumentException, IllegalAccessException { Object key2 = FieldUtil.getAssignedKeyObject(table2.key, obj); if (key2 != null) { String mapTableName = TableManager.getMapTableName(table1, table2); return buildMappingToOneSql(mapTableName, key1, key2, table1, table2); } return null; } /** * 构建N对一关系存储语句 * insert into {table} (key1,key2) values (?,?) */ public static SQLStatement buildMappingToOneSql(String mapTableName, Object key1, Object key2, EntityTable table1, EntityTable table2) throws IllegalArgumentException, IllegalAccessException { if (key2 != null) { StringBuilder sql = new StringBuilder(128); sql.append(INSERT).append(INTO).append(mapTableName) .append(PARENTHESES_LEFT).append(table1.name) .append(COMMA).append(table2.name) .append(PARENTHESES_RIGHT).append(VALUES).append(TWO_HOLDER); SQLStatement stmt = new SQLStatement(); stmt.sql = sql.toString(); stmt.bindArgs = new Object[]{key1, key2}; return stmt; } return null; } /** * 构建查询关系映射语句 * select * from {map table} where {key1} in (?,?...) and {key2} in (?,?...) * 注意:key1List数量不能超过999 */ public static SQLStatement buildQueryRelationSql(Class class1, Class class2, List<String> key1List) { return buildQueryRelationSql(class1, class2, key1List, null); } /** * 构建查询关系映射语句 * select * from {map table} where {key1} in (?,?...) and {key2} in (?,?...) * 注意:keyList 数量不能超过999 */ private static SQLStatement buildQueryRelationSql(Class class1, Class class2, List<String> key1List, List<String> key2List) { final EntityTable table1 = TableManager.getTable(class1); final EntityTable table2 = TableManager.getTable(class2); QueryBuilder builder = new QueryBuilder(class1).queryMappingInfo(class2); ArrayList<String> keyList = new ArrayList<String>(); StringBuilder sb = null; if (!Checker.isEmpty(key1List)) { sb = new StringBuilder(); sb.append(table1.name).append(IN).append(PARENTHESES_LEFT); for (int i = 0, size = key1List.size(); i < size; i++) { if (i == 0) { sb.append(HOLDER); } else { sb.append(COMMA_HOLDER); } } sb.append(PARENTHESES_RIGHT); keyList.addAll(key1List); } if (!Checker.isEmpty(key2List)) { if (sb == null) { sb = new StringBuilder(); } else { sb.append(AND); } sb.append(table2.name).append(IN).append(PARENTHESES_LEFT); for (int i = 0, size = key2List.size(); i < size; i++) { if (i == 0) { sb.append(HOLDER); } else { sb.append(COMMA_HOLDER); } } sb.append(PARENTHESES_RIGHT); keyList.addAll(key2List); } if (sb != null) { builder.where(sb.toString(), keyList.toArray(new String[keyList.size()])); } return builder.createStatement(); } /** * 构建查询关系映射语句 */ public static SQLStatement buildQueryRelationSql(EntityTable table1, EntityTable table2, Object key1) { SQLStatement sqlStatement = new SQLStatement(); sqlStatement.sql = SELECT_ANY_FROM + TableManager.getMapTableName(table1, table2) + WHERE + table1.name + EQUALS_HOLDER; sqlStatement.bindArgs = new String[]{String.valueOf(key1)}; return sqlStatement; } /** * 构建查询关系映射语句 * select * from table2 where key2 = key2; */ public static SQLStatement buildQueryMapEntitySql(EntityTable table2, Object key2) { SQLStatement sqlStatement = new SQLStatement(); sqlStatement.sql = SELECT_ANY_FROM + table2.name + WHERE + table2.key.column + EQUALS_HOLDER; sqlStatement.bindArgs = new String[]{String.valueOf(key2)}; return sqlStatement; } }