From 5b15515432448d31845e3266313ef46f1535e53b Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Fri, 17 Feb 2017 17:15:34 +0100 Subject: [PATCH] Refactored sub bean logic --- src/zutil/db/bean/DBBean.java | 141 ++++++++---------- src/zutil/db/bean/DBBeanConfig.java | 29 ++-- src/zutil/db/bean/DBBeanSQLResultHandler.java | 58 +++---- 3 files changed, 108 insertions(+), 120 deletions(-) diff --git a/src/zutil/db/bean/DBBean.java b/src/zutil/db/bean/DBBean.java index 070fb89..fd6d456 100755 --- a/src/zutil/db/bean/DBBean.java +++ b/src/zutil/db/bean/DBBean.java @@ -151,47 +151,39 @@ public abstract class DBBean { // Generate the SQL StringBuilder query = new StringBuilder(); if (this.id == null) { - query.append("INSERT INTO ").append(config.tableName).append(' '); + query.append("INSERT INTO ").append(config.tableName); StringBuilder sqlCols = new StringBuilder(); StringBuilder sqlValues = new StringBuilder(); for (Field field : config.fields) { - if (!List.class.isAssignableFrom(field.getType())) { - if (sqlCols.length() == 0) - sqlCols.append("("); - else sqlCols.append(", "); - sqlCols.append(DBBeanConfig.getFieldName(field)); + if (sqlCols.length() > 0) + sqlCols.append(", "); + sqlCols.append(DBBeanConfig.getFieldName(field)); - if (sqlValues.length() == 0) - sqlValues.append("VALUES("); - else sqlValues.append(", "); - sqlValues.append("?"); - } + if (sqlValues.length() > 0) + sqlValues.append(", "); + sqlValues.append("?"); } - if (sqlCols.length() > 0) { // Did we generate any query? - query.append(sqlCols).append(") "); - query.append(sqlValues).append(") "); + if (config.fields.size() > 0) { // is there any fields? + query.append(" (").append(sqlCols).append(")"); + query.append(" VALUES(").append(sqlValues).append(")"); } else - query.append("DEFAULT VALUES"); - } else { - query.append("UPDATE ").append(config.tableName).append(' '); + query.append(" DEFAULT VALUES"); + } + else if (config.fields.size() > 0) { // Is there any fields to update? + query.append("UPDATE ").append(config.tableName); StringBuilder sqlSets = new StringBuilder(); for (Field field : config.fields) { - if (!List.class.isAssignableFrom(field.getType())) { - if (sqlSets.length() > 0) - sqlSets.append(", "); - sqlSets.append(DBBeanConfig.getFieldName(field)); - sqlSets.append("=?"); - } + if (sqlSets.length() > 0) + sqlSets.append(", "); + sqlSets.append(DBBeanConfig.getFieldName(field)); + sqlSets.append("=?"); } - if (sqlSets.length() > 0) { // Did we generate any query? - query.append("SET ").append(sqlSets); - query.append("WHERE ").append(config.idColumn).append("=?"); - } else - query = null; // Class has no fields that needs updating + query.append(" SET ").append(sqlSets); + query.append(" WHERE ").append(config.idColumn).append("=?"); } // Check if we have a valid query to run, skip otherwise - if (query != null) { + if (query.length() > 0) { String sql = query.toString(); logger.finest("Save Bean(" + c.getName() + ", id: " + this.getId() + ") query: " + sql); PreparedStatement stmt = db.getPreparedStatement(sql); @@ -209,11 +201,6 @@ public abstract class DBBean { stmt.setObject(index, null); index++; } - // A list of DBBeans - else if (List.class.isAssignableFrom(field.getType()) && - field.getAnnotation(DBLinkTable.class) != null) { - // Do stuff later - } // Normal field else { Object value = getFieldValue(field); @@ -234,52 +221,50 @@ public abstract class DBBean { } // Save sub beans, after we get the parent object id - for (Field field : config.fields) { - if (List.class.isAssignableFrom(field.getType()) && - field.getAnnotation(DBLinkTable.class) != null) { - if (this.id == null) - throw new SQLException("Unknown parent object id"); + for (Field field : config.subBeanFields) { + if (this.id == null) + throw new SQLException("Unknown parent object id"); - List list = (List) getFieldValue(field); - if (list != null) { - DBLinkTable linkTableAnnotation = field.getAnnotation(DBLinkTable.class); - String linkTable = linkTableAnnotation.table(); - String idCol = (linkTableAnnotation.idColumn().isEmpty() ? config.tableName : linkTableAnnotation.idColumn()); - String subIdCol = "id"; + List list = (List) getFieldValue(field); + if (list != null) { + DBLinkTable linkTableAnnotation = field.getAnnotation(DBLinkTable.class); + String linkTable = linkTableAnnotation.table(); + String idCol = (linkTableAnnotation.idColumn().isEmpty() ? config.tableName : linkTableAnnotation.idColumn()); + String subIdCol = "id"; - DBBeanConfig subObjConfig = null; - for (DBBean subObj : list) { - // Save the sub bean - if (recursive || subObj.getId() == null) - subObj.save(db); - if (subObj.getId() == null) { - logger.severe("Unable to save field " + c.getSimpleName() + "." + field.getName() + " with " + subObj.getClass().getSimpleName()); - continue; - } - // Get the Sub object configuration - if (subObjConfig == null) { - subObjConfig = DBBeanConfig.getBeanConfig(subObj.getClass()); - subIdCol = subObjConfig.idColumn; - } - // Save links in link table - String sql; - if (linkTable.equals(subObjConfig.tableName)) - sql = "UPDATE " + linkTable + " SET " + idCol + "=? WHERE " + subIdCol + "=?"; - else - sql = "INSERT INTO " + linkTable + " (" + idCol + ", " + subIdCol + ") SELECT ?,? " + - "WHERE NOT EXISTS(SELECT 1 FROM " + linkTable + " WHERE " + idCol + "=? AND " + subIdCol + "=?);"; - logger.finest("Save sub Bean(" + c.getName() + ", id: " + subObj.getId() + ") query: " + sql); - PreparedStatement subStmt = db.getPreparedStatement(sql); - subStmt.setLong(1, this.id); - subStmt.setLong(2, subObj.getId()); - if (subStmt.getParameterMetaData().getParameterCount() > 2) { - subStmt.setLong(3, this.id); - subStmt.setLong(4, subObj.getId()); - } - DBConnection.exec(subStmt); - } - } - } + DBBeanConfig subObjConfig = null; + for (DBBean subObj : list) { + // Save the sub bean + if (recursive || subObj.getId() == null) + subObj.save(db); + if (subObj.getId() == null) { + logger.severe("Unable to save field "+ c.getSimpleName()+"."+field.getName() + + " with "+ subObj.getClass().getSimpleName() +" because sub bean id is null"); + continue; + } + // Get the Sub object configuration + if (subObjConfig == null) { + subObjConfig = DBBeanConfig.getBeanConfig(subObj.getClass()); + subIdCol = subObjConfig.idColumn; + } + // Save links in link table + String sql; + if (linkTable.equals(subObjConfig.tableName)) + sql = "UPDATE " + linkTable + " SET " + idCol + "=? WHERE " + subIdCol + "=?"; + else + sql = "INSERT INTO " + linkTable + " (" + idCol + ", " + subIdCol + ") SELECT ?,? " + + "WHERE NOT EXISTS(SELECT 1 FROM " + linkTable + " WHERE " + idCol + "=? AND " + subIdCol + "=?);"; + logger.finest("Save sub Bean(" + c.getName() + ", id: " + subObj.getId() + ") query: " + sql); + PreparedStatement subStmt = db.getPreparedStatement(sql); + subStmt.setLong(1, this.id); + subStmt.setLong(2, subObj.getId()); + if (subStmt.getParameterMetaData().getParameterCount() > 2) { + subStmt.setLong(3, this.id); + subStmt.setLong(4, subObj.getId()); + } + DBConnection.exec(subStmt); + } + } } } catch (SQLException e) { throw e; diff --git a/src/zutil/db/bean/DBBeanConfig.java b/src/zutil/db/bean/DBBeanConfig.java index 71c17b1..adf9428 100755 --- a/src/zutil/db/bean/DBBeanConfig.java +++ b/src/zutil/db/bean/DBBeanConfig.java @@ -28,6 +28,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; /** * A Class that contains information about a bean @@ -38,23 +39,23 @@ class DBBeanConfig{ /** The name of the table in the DB **/ - protected String tableName; + public String tableName; /** The name of the id column **/ - protected String idColumn; - /** All the fields in the bean **/ - protected ArrayList fields; + public String idColumn; + /** All normal fields in the bean **/ + public ArrayList fields = new ArrayList<>(); + /** All sub bean fields in the bean **/ + public ArrayList subBeanFields = new ArrayList<>(); - private DBBeanConfig(){ - fields = new ArrayList<>(); - } + private DBBeanConfig(){ } /** * @return the configuration object for the specified class */ - protected static DBBeanConfig getBeanConfig(Class c){ + public static DBBeanConfig getBeanConfig(Class c){ if( !beanConfigs.containsKey( c.getName() ) ) initBeanConfig( c ); return beanConfigs.get( c.getName() ); @@ -81,13 +82,14 @@ class DBBeanConfig{ for( Field field : fields ){ int mod = field.getModifiers(); if( !Modifier.isTransient( mod ) && - !Modifier.isAbstract( mod ) && !Modifier.isFinal( mod ) && !Modifier.isStatic( mod ) && - !Modifier.isInterface( mod ) && - !Modifier.isNative( mod ) && !config.fields.contains( field )){ - config.fields.add( field ); + if (List.class.isAssignableFrom(field.getType()) && + field.getAnnotation(DBBean.DBLinkTable.class) != null) + config.subBeanFields.add( field ); + else + config.fields.add( field ); } } if( tableAnn == null || !tableAnn.superBean() ) @@ -97,10 +99,11 @@ class DBBeanConfig{ beanConfigs.put(c.getName(), config); } - protected static String getFieldName(Field field){ + public static String getFieldName(Field field){ DBBean.DBColumn colAnnotation = field.getAnnotation(DBBean.DBColumn.class); if(colAnnotation != null) return colAnnotation.value(); return field.getName(); } + } \ No newline at end of file diff --git a/src/zutil/db/bean/DBBeanSQLResultHandler.java b/src/zutil/db/bean/DBBeanSQLResultHandler.java index ab57913..602b11d 100755 --- a/src/zutil/db/bean/DBBeanSQLResultHandler.java +++ b/src/zutil/db/bean/DBBeanSQLResultHandler.java @@ -171,40 +171,19 @@ public class DBBeanSQLResultHandler implements SQLResultHandler{ protected void updateBean(ResultSet result, DBBean obj) throws SQLException{ if (obj.readLock.tryLock()) { try { - logger.fine("Updating Bean(" + beanClass.getName() + ") with id: " + obj.getId()); - // Get the rest + logger.fine("Updating Bean("+ beanClass.getName() +") with id: "+ obj.getId()); + // Read fields for (Field field : beanConfig.fields) { String name = DBBeanConfig.getFieldName(field); - // Another DBBean class + // Inline DBBean class if (DBBean.class.isAssignableFrom(field.getType())) { if (db != null) { - Long subid = result.getLong(name); - DBBean subobj = DBBeanCache.get(field.getType(), subid); - if (subobj == null) - subobj = DBBean.load(db, (Class) field.getType(), subid); - obj.setFieldValue(field, subobj); - } else - logger.warning("No DB available to read sub beans"); - } - // A list of DBBeans - else if (List.class.isAssignableFrom(field.getType()) && - field.getAnnotation(DBLinkTable.class) != null) { - if (db != null) { - DBLinkTable linkTable = field.getAnnotation(DBLinkTable.class); - DBBeanConfig subConfig = DBBeanConfig.getBeanConfig(linkTable.beanClass()); - String linkTableName = linkTable.table(); - String subTable = subConfig.tableName; - String idcol = (linkTable.idColumn().isEmpty() ? beanConfig.tableName : linkTable.idColumn()); - - // Load list from link table - String subsql = "SELECT subObjTable.* FROM " + linkTableName + " as linkTable, " + subTable + " as subObjTable WHERE linkTable." + idcol + "=? AND linkTable." + subConfig.idColumn + "=subObjTable." + subConfig.idColumn; - logger.finest("List Load Query: " + subsql); - PreparedStatement subStmt = db.getPreparedStatement(subsql); - subStmt.setObject(1, obj.getId()); - List list = DBConnection.exec(subStmt, - DBBeanSQLResultHandler.createList(linkTable.beanClass(), db)); - obj.setFieldValue(field, list); + Long subId = result.getLong(name); + DBBean subObj = DBBeanCache.get(field.getType(), subId); + if (subObj == null) + subObj = DBBean.load(db, (Class) field.getType(), subId); + obj.setFieldValue(field, subObj); } else logger.warning("No DB available to read sub beans"); } @@ -213,7 +192,28 @@ public class DBBeanSQLResultHandler implements SQLResultHandler{ obj.setFieldValue(field, result.getObject(name)); } } + // Read sub beans + if (db != null) { + for (Field field : beanConfig.subBeanFields) { + DBLinkTable linkTable = field.getAnnotation(DBLinkTable.class); + DBBeanConfig subConfig = DBBeanConfig.getBeanConfig(linkTable.beanClass()); + String linkTableName = linkTable.table(); + String subTable = subConfig.tableName; + String idCol = (linkTable.idColumn().isEmpty() ? beanConfig.tableName : linkTable.idColumn()); + // Load list from link table + String subSql = "SELECT subObjTable.* FROM "+ linkTableName +" as linkTable, "+ subTable +" as subObjTable WHERE linkTable."+idCol+"=? AND linkTable."+subConfig.idColumn+"=subObjTable."+subConfig.idColumn; + logger.finest("List Load Query: " + subSql); + PreparedStatement subStmt = db.getPreparedStatement(subSql); + subStmt.setObject(1, obj.getId()); + List list = DBConnection.exec(subStmt, + DBBeanSQLResultHandler.createList(linkTable.beanClass(), db)); + obj.setFieldValue(field, list); + } + } else + logger.warning("No DB available to read sub beans"); + + // Call post listener obj.postUpdateAction(); } finally { obj.readLock.unlock();