Refactored sub bean logic

This commit is contained in:
Ziver Koc 2017-02-17 17:15:34 +01:00
parent 7c4c536ce5
commit 5b15515432
3 changed files with 108 additions and 120 deletions

View file

@ -151,47 +151,39 @@ public abstract class DBBean {
// Generate the SQL // Generate the SQL
StringBuilder query = new StringBuilder(); StringBuilder query = new StringBuilder();
if (this.id == null) { if (this.id == null) {
query.append("INSERT INTO ").append(config.tableName).append(' '); query.append("INSERT INTO ").append(config.tableName);
StringBuilder sqlCols = new StringBuilder(); StringBuilder sqlCols = new StringBuilder();
StringBuilder sqlValues = new StringBuilder(); StringBuilder sqlValues = new StringBuilder();
for (Field field : config.fields) { for (Field field : config.fields) {
if (!List.class.isAssignableFrom(field.getType())) { if (sqlCols.length() > 0)
if (sqlCols.length() == 0) sqlCols.append(", ");
sqlCols.append("(");
else sqlCols.append(", ");
sqlCols.append(DBBeanConfig.getFieldName(field)); sqlCols.append(DBBeanConfig.getFieldName(field));
if (sqlValues.length() == 0) if (sqlValues.length() > 0)
sqlValues.append("VALUES("); sqlValues.append(", ");
else sqlValues.append(", ");
sqlValues.append("?"); sqlValues.append("?");
} }
} if (config.fields.size() > 0) { // is there any fields?
if (sqlCols.length() > 0) { // Did we generate any query? query.append(" (").append(sqlCols).append(")");
query.append(sqlCols).append(") "); query.append(" VALUES(").append(sqlValues).append(")");
query.append(sqlValues).append(") ");
} else } else
query.append("DEFAULT VALUES"); query.append(" DEFAULT VALUES");
} else { }
query.append("UPDATE ").append(config.tableName).append(' '); else if (config.fields.size() > 0) { // Is there any fields to update?
query.append("UPDATE ").append(config.tableName);
StringBuilder sqlSets = new StringBuilder(); StringBuilder sqlSets = new StringBuilder();
for (Field field : config.fields) { for (Field field : config.fields) {
if (!List.class.isAssignableFrom(field.getType())) {
if (sqlSets.length() > 0) if (sqlSets.length() > 0)
sqlSets.append(", "); sqlSets.append(", ");
sqlSets.append(DBBeanConfig.getFieldName(field)); sqlSets.append(DBBeanConfig.getFieldName(field));
sqlSets.append("=?"); sqlSets.append("=?");
} }
} query.append(" SET ").append(sqlSets);
if (sqlSets.length() > 0) { // Did we generate any query? query.append(" WHERE ").append(config.idColumn).append("=?");
query.append("SET ").append(sqlSets);
query.append("WHERE ").append(config.idColumn).append("=?");
} else
query = null; // Class has no fields that needs updating
} }
// Check if we have a valid query to run, skip otherwise // Check if we have a valid query to run, skip otherwise
if (query != null) { if (query.length() > 0) {
String sql = query.toString(); String sql = query.toString();
logger.finest("Save Bean(" + c.getName() + ", id: " + this.getId() + ") query: " + sql); logger.finest("Save Bean(" + c.getName() + ", id: " + this.getId() + ") query: " + sql);
PreparedStatement stmt = db.getPreparedStatement(sql); PreparedStatement stmt = db.getPreparedStatement(sql);
@ -209,11 +201,6 @@ public abstract class DBBean {
stmt.setObject(index, null); stmt.setObject(index, null);
index++; index++;
} }
// A list of DBBeans
else if (List.class.isAssignableFrom(field.getType()) &&
field.getAnnotation(DBLinkTable.class) != null) {
// Do stuff later
}
// Normal field // Normal field
else { else {
Object value = getFieldValue(field); Object value = getFieldValue(field);
@ -234,9 +221,7 @@ public abstract class DBBean {
} }
// Save sub beans, after we get the parent object id // Save sub beans, after we get the parent object id
for (Field field : config.fields) { for (Field field : config.subBeanFields) {
if (List.class.isAssignableFrom(field.getType()) &&
field.getAnnotation(DBLinkTable.class) != null) {
if (this.id == null) if (this.id == null)
throw new SQLException("Unknown parent object id"); throw new SQLException("Unknown parent object id");
@ -253,7 +238,8 @@ public abstract class DBBean {
if (recursive || subObj.getId() == null) if (recursive || subObj.getId() == null)
subObj.save(db); subObj.save(db);
if (subObj.getId() == null) { if (subObj.getId() == null) {
logger.severe("Unable to save field " + c.getSimpleName() + "." + field.getName() + " with " + subObj.getClass().getSimpleName()); logger.severe("Unable to save field "+ c.getSimpleName()+"."+field.getName() +
" with "+ subObj.getClass().getSimpleName() +" because sub bean id is null");
continue; continue;
} }
// Get the Sub object configuration // Get the Sub object configuration
@ -280,7 +266,6 @@ public abstract class DBBean {
} }
} }
} }
}
} catch (SQLException e) { } catch (SQLException e) {
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {

View file

@ -28,6 +28,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
/** /**
* A Class that contains information about a bean * A Class that contains information about a bean
@ -38,23 +39,23 @@ class DBBeanConfig{
/** The name of the table in the DB **/ /** The name of the table in the DB **/
protected String tableName; public String tableName;
/** The name of the id column **/ /** The name of the id column **/
protected String idColumn; public String idColumn;
/** All the fields in the bean **/ /** All normal fields in the bean **/
protected ArrayList<Field> fields; public ArrayList<Field> fields = new ArrayList<>();
/** All sub bean fields in the bean **/
public ArrayList<Field> subBeanFields = new ArrayList<>();
private DBBeanConfig(){ private DBBeanConfig(){ }
fields = new ArrayList<>();
}
/** /**
* @return the configuration object for the specified class * @return the configuration object for the specified class
*/ */
protected static DBBeanConfig getBeanConfig(Class<? extends DBBean> c){ public static DBBeanConfig getBeanConfig(Class<? extends DBBean> c){
if( !beanConfigs.containsKey( c.getName() ) ) if( !beanConfigs.containsKey( c.getName() ) )
initBeanConfig( c ); initBeanConfig( c );
return beanConfigs.get( c.getName() ); return beanConfigs.get( c.getName() );
@ -81,12 +82,13 @@ class DBBeanConfig{
for( Field field : fields ){ for( Field field : fields ){
int mod = field.getModifiers(); int mod = field.getModifiers();
if( !Modifier.isTransient( mod ) && if( !Modifier.isTransient( mod ) &&
!Modifier.isAbstract( mod ) &&
!Modifier.isFinal( mod ) && !Modifier.isFinal( mod ) &&
!Modifier.isStatic( mod ) && !Modifier.isStatic( mod ) &&
!Modifier.isInterface( mod ) &&
!Modifier.isNative( mod ) &&
!config.fields.contains( field )){ !config.fields.contains( field )){
if (List.class.isAssignableFrom(field.getType()) &&
field.getAnnotation(DBBean.DBLinkTable.class) != null)
config.subBeanFields.add( field );
else
config.fields.add( field ); config.fields.add( field );
} }
} }
@ -97,10 +99,11 @@ class DBBeanConfig{
beanConfigs.put(c.getName(), config); 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); DBBean.DBColumn colAnnotation = field.getAnnotation(DBBean.DBColumn.class);
if(colAnnotation != null) if(colAnnotation != null)
return colAnnotation.value(); return colAnnotation.value();
return field.getName(); return field.getName();
} }
} }

View file

@ -171,40 +171,19 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
protected void updateBean(ResultSet result, DBBean obj) throws SQLException{ protected void updateBean(ResultSet result, DBBean obj) throws SQLException{
if (obj.readLock.tryLock()) { if (obj.readLock.tryLock()) {
try { try {
logger.fine("Updating Bean(" + beanClass.getName() + ") with id: " + obj.getId()); logger.fine("Updating Bean("+ beanClass.getName() +") with id: "+ obj.getId());
// Get the rest // Read fields
for (Field field : beanConfig.fields) { for (Field field : beanConfig.fields) {
String name = DBBeanConfig.getFieldName(field); String name = DBBeanConfig.getFieldName(field);
// Another DBBean class // Inline DBBean class
if (DBBean.class.isAssignableFrom(field.getType())) { if (DBBean.class.isAssignableFrom(field.getType())) {
if (db != null) { if (db != null) {
Long subid = result.getLong(name); Long subId = result.getLong(name);
DBBean subobj = DBBeanCache.get(field.getType(), subid); DBBean subObj = DBBeanCache.get(field.getType(), subId);
if (subobj == null) if (subObj == null)
subobj = DBBean.load(db, (Class<? extends DBBean>) field.getType(), subid); subObj = DBBean.load(db, (Class<? extends DBBean>) field.getType(), subId);
obj.setFieldValue(field, subobj); 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<? extends DBBean> list = DBConnection.exec(subStmt,
DBBeanSQLResultHandler.createList(linkTable.beanClass(), db));
obj.setFieldValue(field, list);
} else } else
logger.warning("No DB available to read sub beans"); logger.warning("No DB available to read sub beans");
} }
@ -213,7 +192,28 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
obj.setFieldValue(field, result.getObject(name)); 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<? extends DBBean> 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(); obj.postUpdateAction();
} finally { } finally {
obj.readLock.unlock(); obj.readLock.unlock();