java generische Konstruktoren
Momentan habe ich folgende code ruft Daten aus der Datenbank und erstellen Sie dann eine User
. Dieser code wird verwendet in vielen meiner classe zu erstellen, die andere Objekte wie News
, Comments
etc...
Es nutzt apache commons dbutils.
final ResultSetHandler<User> handler = new ResultSetHandler<User>() {
@Override
public User handle(ResultSet rs) throws SQLException {
User user = null;
if (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
}
return user;
}
};
final User user = run.query(
"SELECT id, username, password FROM users WHERE username = ? AND active = 2 LIMIT 1;", handler,
username);
Wäre es möglich, wickeln Sie die QueryRunner
in einer generischen Klasse und überschreiben Sie die Methode " query (also die handler instantiieren der generischen T
mit dem ResultSet. Ich würde sicherstellen, dass alle T
geben würde ahve ein Konstruktor akzeptiert ein ResultSet
.
Etwa so :
public class QueryExecuter<T> extends QueryRunner {
private ResultSetHandler<T> _handler;
public QueryExecuter(){//The T type was for testing haha
super();
handler = new ResultSetHandler<T>() {
@Override
public T handle(ResultSet rs) throws SQLException {
T object = null;
if (rs.next()) {
object = new T(rs);
}
return object;
}
};
}
}
Ich weiß nicht, ob Sie verstehen werden, aber ich hoffe doch, Fragen Sie mich, wenn Sie mehr details oder eine bessere Erklärung.
BEARBEITEN
Dachte ich, ich könnte mit einem AbstractClass statt des generischen Typs, die alle die verschiedenen Objekte erstreckt sich aber, wie es scheint, ich kann nicht schreiben, eine abstrakte Konstruktor. Werde ich haben, um eine statische Methode, die eine Instanz des Objekts wie:
public abstract class DatabaseEntity {
public static abstract DatabaseEntity create(ResultSet rs);//even this doesn't work...
}
- warum brauchen Sie, um pass
T type
im Konstruktor? - verwenden Sie reflektion, die Sie aufrufen können und die Klasse Konstruktor mit ResultSet
Du musst angemeldet sein, um einen Kommentar abzugeben.
Möglich, ja? Aber es ist eine schlechte Idee.
Könnten Sie tun:
Misch-domain und Datenbank ist eine schlechte Idee, jedoch. Was wäre besser, wäre allerdings zu definieren, abtract-Methode erzeugt das Objekt, basierend auf der Ergebnismenge:
Dann in Ihrer Umsetzung Klasse, Sie brauchen nur eine
create()
- Methode anstelle der Behandlung das Ergebnis selbst festlegen, zum Beispiel:Könnte man etwas tun (wenn man die Klasse des Objekts zu erstellen, und verwenden Sie reflektion, um Ihr Konstruktor aufgerufen werden), aber ich fände es schlechtes design haben die POJO-abhängig von JDBC und wissen nicht nur, wie es in der Datenbank gespeichert, sondern auch die Aliase verwendet wurden, die in der Abfrage verwendet, um es zu laden.
Kurz gesagt, es ist nicht die Verantwortung des Benutzers POJO-Konstruktor handle ein ResultSet von einem externen, unbekannten Abfrage.
Könnte man das design ein AbstractSingleEntityHandler Superklasse, das würde nur die
block, und würden die Delegierten die wirkliche Einheit der Schöpfung, um eine abstrakte Methode, aber Sie würden nicht viel zu gewinnen.
query
Methode wäre, direkt das Objekt zurückgeben.Ich glaube nicht, dass es möglich ist, dies zu tun in Java. Sie können nicht erstellen Sie eine Instanz der
T
im Allgemeinen. Generics in java sind nicht wirklich templates wie in C++, Sie werden nur syntax-Zucker um einobject
was entfernt den und wirft induziert kompilieren Warnungen.Gibt es keine Möglichkeit wie in C# zu beschränken
T
so dass es muss über einen Konstruktor verfügen.Ihre beste Wette, wenn es wirklich nötig ist zum auflösen der entsprechenden Klasse mit der spiegelung, aber auch dann läuft man in problem, da Sie nicht wissen, die runtime-Klasse von T, wie die Methode aufgerufen wird - diese Informationen werden entfernt aus dem java-bytecode. So bleibt man mit bestehen der Klasse in die Methode, um die Reflexion über Sie. Und ich bin mir nicht sicher, dies ist eine gute design-Idee sowieso.
Class<T>
.