I'm coding a SQL generator based on java reflection (it's intended to be used with generics in the future). I receive an object as a parameter to generate the table name, fields and field values (for insert and update operations), but in my DAO classes I'm instantiating a new empty object, that won't be used anywhere else in the code, just obtain these information. Is there a way to cast some sort of "ghost" object, which won't occupy memory space, to serve this purpose?
This is the class responsible for generating the SQL:
public abstract class DynamicSQL
{
public static final boolean NO_ID = false;
public static final boolean WITH_ID = true;
private Vector<Field> get_class_fields(Object obj, id_wanted)
{
Class<?> cls = obj.getClass();
Vector<Field> fields = new Vector<>();
while(cls != Object.class)
{
Field[] cls_flds = cls.getDeclaredFields();
fields.addAll(Arrays.asList(cls_flds));
cls = cls.getSuperclass();
}
// If the id is not wanted, it is removed here
if(!id_wanted)
{
for(int i = 0; i < fields.size(); i += 1)
{
Field f = fields.get(i);
if(f.getName().equals("id"))
fields.remove(f);
}
}
return fields;
}
private Vector<String> get_fields_names(Object obj, boolean id)
{
Vector<Field> fields = get_class_fields(obj, id);
Vector<String> field_names = new Vector<>();
for(Field f : fields)
{
field_names.add(f.getName());
}
return field_names;
}
private String get_table_name(Object obj)
{
String[] class_name = obj.getClass().getName().toLowerCase().split("\\.");
String table_name = class_name[class_name.length - 1];
return table_name;
}
protected String select_sql(Object obj)
{
String table_name = get_table_name(obj);
Vector<String> fields = get_fields_names(obj, WITH_ID);
String sql = "SELECT ";
for(int i = 0; i < fields.size(); i += 1)
{
sql += fields.get(i);
if(i < fields.size()-1) sql += ", ";
}
sql += " FROM " + table_name;
return sql;
}
//work in progress...
}
This is my DAO class:
public class CustomerDAO extends DynamicSQL implements IDAO<Customer>
{
@Override
public Vector<Customer> list_all()
{
Vector<Customer> customers = new Vector<>();
//Here I instantiate the object I'm willing to get rid of
String sql = select_sql(new Customer.Builder().build(), DynamicSQL.WITH_ID);
try
{
ResultSet rs = ConnectionFactory.get_instance().execute_query(sql);
while(rs.next())
{
customers.add(new Cliente.Builder().
id(rs.getLong("id")).
nome(rs.getString("nome")).
endereco(rs.getString("endereco")).
telefone(rs.getString("telefone")).
build()
);
}
}
catch(SQLException e)
{
e.printStackTrace();
}
return customers;
}
//other method overrides and implementation...
}
Everything runs fine, but I'm annoyed with that unnecessary object instantiation. Is there another way to do it, or do I need to instantiate that object anyway?