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
|
||||
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<DBBean> list = (List<DBBean>) 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<DBBean> list = (List<DBBean>) 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;
|
||||
|
|
|
|||
|
|
@ -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<Field> fields;
|
||||
public String idColumn;
|
||||
/** All normal fields in the bean **/
|
||||
public ArrayList<Field> fields = new ArrayList<>();
|
||||
/** All sub bean fields in the bean **/
|
||||
public ArrayList<Field> subBeanFields = new ArrayList<>();
|
||||
|
||||
|
||||
private DBBeanConfig(){
|
||||
fields = new ArrayList<>();
|
||||
}
|
||||
private DBBeanConfig(){ }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @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() ) )
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -171,40 +171,19 @@ public class DBBeanSQLResultHandler<T> implements SQLResultHandler<T>{
|
|||
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<? extends DBBean>) 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<? extends DBBean> 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<? extends DBBean>) field.getType(), subId);
|
||||
obj.setFieldValue(field, subObj);
|
||||
} else
|
||||
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));
|
||||
}
|
||||
}
|
||||
// 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();
|
||||
} finally {
|
||||
obj.readLock.unlock();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue