Klassen dynamisch mit Java erstellen
Habe ich versucht, Informationen zu finden, diese haben aber kommen mit leeren Händen:
Entnehme ich, es ist möglich, eine Klasse zu erstellen, die dynamisch in Java unter Verwendung von reflektion oder proxies, aber ich kann nicht herausfinden, wie. Ich bin die Implementierung einer einfachen Datenbank-framework, wo ich erstellen Sie die SQL-Abfragen unter Verwendung von reflektion ab. Die Methode bekommt das Objekt mit der Datenbank-Felder als parameter und die Abfrage erstellt, die Grundlage. Aber es wäre sehr hilfreich, wenn ich kann auch das Objekt selbst dynamisch, so würde ich nicht über die Notwendigkeit zu haben, eine einfache Daten-wrapper-Objekt für jeden Tisch.
Den dynamischen Klassen würden nur noch einfache Felder (String
Integer
Double
), z.B.
public class Data {
public Integer id;
public String name;
}
Ist das möglich und wie kann ich dies tun?
EDIT: Dies ist, wie würde ich dieses verwenden:
/** Creates an SQL query for updating a row's values in the database.
*
* @param entity Table name.
* @param toUpdate Fields and values to update. All of the fields will be
* updated, so each field must have a meaningful value!
* @param idFields Fields used to identify the row(s).
* @param ids Id values for id fields. Values must be in the same order as
* the fields.
* @return
*/
@Override
public String updateItem(String entity, Object toUpdate, String[] idFields,
String[] ids) {
StringBuilder sb = new StringBuilder();
sb.append("UPDATE ");
sb.append(entity);
sb.append("SET ");
for (Field f: toUpdate.getClass().getDeclaredFields()) {
String fieldName = f.getName();
String value = new String();
sb.append(fieldName);
sb.append("=");
sb.append(formatValue(f));
sb.append(",");
}
/* Remove last comma */
sb.deleteCharAt(sb.toString().length()-1);
/* Add where clause */
sb.append(createWhereClause(idFields, ids));
return sb.toString();
}
/** Formats a value for an sql query.
*
* This function assumes that the field type is equivalent to the field
* in the database. In practice this means that this field support two
* types of fields: string (varchar) and numeric.
*
* A string type field will be escaped with single parenthesis (') because
* SQL databases expect that. Numbers are returned as-is.
*
* If the field is null, a string containing "NULL" is returned instead.
*
* @param f The field where the value is.
* @return Formatted value.
*/
String formatValue(Field f) {
String retval = null;
String type = f.getClass().getName();
if (type.equals("String")) {
try {
String value = (String)f.get(f);
if (value != null) {
retval = "'" + value + "'";
} else {
retval = "NULL";
}
} catch (Exception e) {
System.err.println("No such field: " + e.getMessage());
}
} else if (type.equals("Integer")) {
try {
Integer value = (Integer)f.get(f);
if (value != null) {
retval = String.valueOf(value);
} else {
retval = "NULL";
}
} catch (Exception e) {
System.err.println("No such field: " + e.getMessage());
}
} else {
try {
String value = (String) f.get(f);
if (value != null) {
retval = value;
} else {
retval = "NULL";
}
} catch (Exception e) {
System.err.println("No such field: " + e.getMessage());
}
}
return retval;
}
InformationsquelleAutor der Frage Makis | 2010-02-23
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ist es möglich, zum generieren von Klassen (über cglibasmjavassistbcel), aber Sie sollten es nicht tun, die Art und Weise. Warum?
Object
alle Felder mit der spiegelung - nicht eine gute IdeeWenn Sie wollen einfach nur die Daten in einem nicht definierten format, dann können Sie es zurück in ein array, wie
Object[]
oderMap<String, Object>
wenn Sie wollen, dass Sie mit Namen, und bekommen es von dort - so sparen Sie viel ärger mit unnötigen Klasse-generation für den der einzige Zweck enthalten einige Daten, die erhalten werden durch Reflexion.Was Sie tun können, stattdessen haben vordefinierte Klassen enthalten die Daten und übergeben Sie als Argumente an Methoden Abfragen. Zum Beispiel:
So können Sie mithilfe von reflektion auf dem übergebenen
expectedResultClass
ein neues Objekt zu erstellen, geben Sie und füllen Sie es mit dem Ergebnis der Abfrage.Sagte, ich denke, Sie könnte etwas vorhandenes, wie ein ORM framework (Hibernate, EclipseLink), Frühling
JdbcTemplate
usw.InformationsquelleAutor der Antwort Bozho
Es gibt viele verschiedene Wege, dies zu erreichen (e.g-proxies, ASM), aber der einfachste Ansatz, eine, die Sie beginnen mit, wenn Prototypen ist:
InformationsquelleAutor der Antwort Amir Afghani
Es wird ein paar Minuten dauern, um zu erstellen Sie eine data-model-Klasse für jede Tabelle, die können Sie ganz einfach anzeigen, um die Datenbank mit einem ORM wie Hibernate oder schreiben Sie Ihre eigenen JDBC-DAOs. Es ist viel einfacher, als eintauchen tief in Reflexion.
Können Sie ein Dienstprogramm, das abfragt, die Datenbank-Struktur für eine Tabelle, und legt die Daten-Modell-Klassen und DAO für Sie. Alternativ könnt Ihr das Modell in Java und erstellen Sie ein Dienstprogramm zum erstellen des Datenbankschemas und DAO aus, dass (mit reflection und Java-5-Annotationen zu unterstützen). Vergessen Sie nicht, dass javaFieldNames unterscheiden sich von database_column_names in der Regel.
InformationsquelleAutor der Antwort JeeBee
Ich würde nicht versuchen, diese entweder. Eine Klasse, die Daten und code, welche Art von code Sie planen, auf den Umgang mit dynamischen Daten?
Was Sie wahrscheinlich wollen, ist eine Sammlung-oder vielleicht gerade Hibernate.
Können Sie spielen viele tricks, die mit der Sammlung, um es zu tun, was Sie wollen. Statt die Objekte direkt in die Sammlung, Sie können wickeln Sie Sie in meta-Objekte mit Daten, die sicherstellt, dass Ihre Art oder, dass Sie nicht null sind. Sie können wickeln Sie Ihre gesamte Sammlung in einer Klasse erzwingt Typsicherheit, Vollständigkeit und Beziehungen. Ich habe sogar meine Sammlungen die Fähigkeit zu nehmen "Validator" - Klassen zur Validierung der Daten zugewiesen wird.
Validierungen, die Struktur und die ersten Einträge kommen aus einer Datenbank, aus XML-oder code.
InformationsquelleAutor der Antwort Bill K
Dies ist möglich, aber (ich glaube) man braucht so etwas wie ASM oder BCEL.
Alternativ könnte man etwas mit mehr power (wie Grooviger).
InformationsquelleAutor der Antwort Drew Wills