Refactored sub bean logic
This commit is contained in:
parent
7c4c536ce5
commit
5b15515432
3 changed files with 108 additions and 120 deletions
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue